Initial commit
[mono.git] / mcs / class / referencesource / mscorlib / system / security / cryptography / rijndaelmanagedtransform.cs
1 using System.Diagnostics.Contracts;
2 // ==++==
3 // 
4 //   Copyright (c) Microsoft Corporation.  All rights reserved.
5 // 
6 // ==--==
7 // <OWNER>[....]</OWNER>
8 // 
9
10 //
11 // RijndaelManagedTransform.cs
12 //
13
14 namespace System.Security.Cryptography
15 {
16     [Serializable]
17     internal enum RijndaelManagedTransformMode {
18         Encrypt = 0,
19         Decrypt = 1
20     }
21
22     [System.Runtime.InteropServices.ComVisible(true)]
23     public sealed class RijndaelManagedTransform : ICryptoTransform {
24         private CipherMode m_cipherMode;
25         private PaddingMode m_paddingValue;
26         private RijndaelManagedTransformMode m_transformMode;
27
28         private int m_blockSizeBits;
29         private int m_blockSizeBytes;
30         private int m_inputBlockSize;
31         private int m_outputBlockSize;
32
33         private int[] m_encryptKeyExpansion;
34         private int[] m_decryptKeyExpansion;
35
36         private int m_Nr;
37         private int m_Nb;
38         private int m_Nk;
39
40         private int[] m_encryptindex = null;
41         private int[] m_decryptindex = null;
42
43         private int[] m_IV;
44         private int[] m_lastBlockBuffer;
45         private byte[] m_depadBuffer;
46         private byte[] m_shiftRegister;
47
48         internal RijndaelManagedTransform (byte[] rgbKey,
49                                            CipherMode mode,
50                                            byte[] rgbIV,
51                                            int blockSize,
52                                            int feedbackSize,
53                                            PaddingMode PaddingValue,
54                                            RijndaelManagedTransformMode transformMode) {
55             if (rgbKey == null)
56                 throw new ArgumentNullException("rgbKey");
57             Contract.EndContractBlock();
58
59 #if !FEATURE_CRYPTO
60             Contract.Assert(mode == CipherMode.CBC, "CipherMode is unsupported on CoreCLR");
61             Contract.Assert(PaddingValue == PaddingMode.PKCS7, "PaddingMode is unsupported on CoreCLR");
62 #endif // !FEATURE_CRYPTO
63
64             m_blockSizeBits = blockSize;
65             m_blockSizeBytes = blockSize / 8;
66             m_cipherMode = mode;
67             m_paddingValue = PaddingValue;
68             m_transformMode = transformMode;
69             m_Nb = blockSize / 32;
70             m_Nk = rgbKey.Length / 4;
71
72             int S1 = m_Nb > 6 ? 3 : 2;
73             int S2 = m_Nb > 6 ? 4 : 3;
74
75             // Precompute the modulus operations: these are performance killers when called frequently
76             int[] encryptindex1 = new int[m_Nb];
77             int[] encryptindex2 = new int[m_Nb];
78             int[] encryptindex3 = new int[m_Nb];
79
80             int[] decryptindex1 = new int[m_Nb];
81             int[] decryptindex2 = new int[m_Nb];
82             int[] decryptindex3 = new int[m_Nb];
83
84             for (int j=0; j < m_Nb; j++) {
85                 encryptindex1[j] = (j + 1) % m_Nb;
86                 encryptindex2[j] = (j + S1) % m_Nb;
87                 encryptindex3[j] = (j + S2) % m_Nb;
88                 decryptindex1[j] = (j -1  + m_Nb) % m_Nb;
89                 decryptindex2[j] = (j -S1 + m_Nb) % m_Nb;
90                 decryptindex3[j] = (j -S2 + m_Nb) % m_Nb;
91             }
92
93             m_encryptindex = new int[m_Nb * 3];
94             Array.Copy(encryptindex1, 0, m_encryptindex, 0, m_Nb);
95             Array.Copy(encryptindex2, 0, m_encryptindex, m_Nb, m_Nb);
96             Array.Copy(encryptindex3, 0, m_encryptindex, m_Nb * 2, m_Nb);
97
98             m_decryptindex = new int[m_Nb * 3];
99             Array.Copy(decryptindex1, 0, m_decryptindex, 0, m_Nb);
100             Array.Copy(decryptindex2, 0, m_decryptindex, m_Nb, m_Nb);
101             Array.Copy(decryptindex3, 0, m_decryptindex, m_Nb * 2, m_Nb);
102
103             switch (m_cipherMode) {
104                 case CipherMode.ECB:
105                 case CipherMode.CBC:
106                     m_inputBlockSize = m_blockSizeBytes;
107                     m_outputBlockSize = m_blockSizeBytes;
108                     break;
109
110                 case CipherMode.CFB:
111                     m_inputBlockSize = feedbackSize / 8;
112                     m_outputBlockSize = feedbackSize / 8;
113                     break;
114
115                 default:
116                     throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidCipherMode"));
117             }
118
119             // On CorECLR we only support CBC mode
120 #if FEATURE_CRYPTO
121             if (mode == CipherMode.CBC || mode == CipherMode.CFB) {
122 #endif // FEATURE_CRYPTO
123                 if (rgbIV == null)
124                     throw new ArgumentNullException("rgbIV");
125                 if (rgbIV.Length / 4 != m_Nb)
126                     throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidIVSize"));
127
128                 m_IV = new int[m_Nb];
129                 int index = 0;
130                 for (int i = 0; i < m_Nb; ++i) {
131                     int i0 = rgbIV[index++];
132                     int i1 = rgbIV[index++];
133                     int i2 = rgbIV[index++];
134                     int i3 = rgbIV[index++];
135                     m_IV[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0;
136                 }
137 #if FEATURE_CRYPTO
138             }
139 #endif // FEATURE_CRYPTO
140
141             GenerateKeyExpansion(rgbKey);
142
143 #if FEATURE_CRYPTO // see code:System.Security.Cryptography.RijndaelManaged#CoreCLRRijndaelModes
144             if (m_cipherMode == CipherMode.CBC) {
145 #endif // FEATURE_CRYPTO
146                 m_lastBlockBuffer = new int[m_Nb];
147                 Buffer.InternalBlockCopy(m_IV, 0, m_lastBlockBuffer, 0, m_blockSizeBytes);
148 #if FEATURE_CRYPTO
149             }
150 #endif // FEATURE_CRYPTO
151
152 #if FEATURE_CRYPTO
153             if (m_cipherMode == CipherMode.CFB) {
154                 m_shiftRegister = new byte[4*m_Nb];
155                 Buffer.InternalBlockCopy(m_IV, 0, m_shiftRegister, 0, 4*m_Nb);
156             }
157 #endif // FEATURE_CRYPTO
158         }
159
160 #if FEATURE_CORECLR
161         void IDisposable.Dispose()
162 #else
163         public void Dispose()
164 #endif
165         {
166             Dispose(true);
167         }
168
169         public void Clear() {
170            Dispose(true);
171         }
172
173         private void Dispose (bool disposing) {
174             if (disposing) {
175                 // We need to always zeroize the following fields because they contain sensitive data
176                 if (m_IV != null) {
177                     Array.Clear(m_IV, 0, m_IV.Length);
178                     m_IV = null;
179                 }
180                 if (m_lastBlockBuffer != null) {
181                     Array.Clear(m_lastBlockBuffer, 0, m_lastBlockBuffer.Length);
182                     m_lastBlockBuffer = null;
183                 }
184                 if (m_encryptKeyExpansion != null) {
185                     Array.Clear(m_encryptKeyExpansion, 0, m_encryptKeyExpansion.Length);
186                     m_encryptKeyExpansion = null;
187                 }
188                 if (m_decryptKeyExpansion != null) {
189                     Array.Clear(m_decryptKeyExpansion, 0, m_decryptKeyExpansion.Length);
190                     m_decryptKeyExpansion = null;
191                 }
192                 if (m_depadBuffer != null) {
193                     Array.Clear(m_depadBuffer, 0, m_depadBuffer.Length);
194                     m_depadBuffer = null;
195                 }
196                 if (m_shiftRegister != null) {
197                     Array.Clear(m_shiftRegister, 0, m_shiftRegister.Length);
198                     m_shiftRegister = null;
199                 }
200             }
201         }
202
203         //
204         // ICryptoTransform methods and properties.
205         //
206
207         public int BlockSizeValue {
208             get {
209                 return m_blockSizeBits;
210             }
211         }
212
213         public int InputBlockSize {
214             get {
215                 return m_inputBlockSize;
216             }
217         }
218
219         public int OutputBlockSize {
220             get {
221                 return m_outputBlockSize;
222             }
223         }
224
225         public bool CanTransformMultipleBlocks {
226             get {
227                 return true;
228             }
229         }
230
231         public bool CanReuseTransform {
232             get {
233                 return true;
234             }
235         }
236
237         public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) {
238             // Note: special handling required if decrypting & using padding because the padding adds to the end of the last
239             // block, we have to buffer an entire block's worth of bytes in case what I just transformed turns out to be 
240             // the last block Then in TransformFinalBlock we strip off the padding.
241
242             if (inputBuffer == null) throw new ArgumentNullException("inputBuffer");
243             if (outputBuffer == null) throw new ArgumentNullException("outputBuffer");
244             if (inputOffset < 0) throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
245             if (inputCount <= 0 || (inputCount % InputBlockSize != 0) || (inputCount > inputBuffer.Length)) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
246             if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
247             Contract.EndContractBlock();
248
249             if (m_transformMode == RijndaelManagedTransformMode.Encrypt) {
250                 // if we're encrypting we can always push out the bytes because no padding mode
251                 // removes bytes during encryption
252                 return EncryptData(inputBuffer,
253                                    inputOffset,
254                                    inputCount,
255                                    ref outputBuffer,
256                                    outputOffset,
257                                    m_paddingValue,
258                                    false);
259             }
260             else {
261 #if FEATURE_CRYPTO // see code:System.Security.Cryptography.RijndaelManaged#CoreCLRRijndaelModes
262                 if (m_paddingValue == PaddingMode.Zeros || m_paddingValue == PaddingMode.None) {
263                     // like encryption, if we're using None or Zeros padding on decrypt we can write out all
264                     // the bytes.  Note that we cannot depad a block partially padded with Zeros because
265                     // we can't tell if those zeros are plaintext or pad.
266                     return DecryptData(inputBuffer, inputOffset, inputCount, ref outputBuffer, outputOffset, m_paddingValue, false);
267                 }
268                 else {
269 #endif // FEATURE_CRYPTO
270                     // OK, now we're in the special case.  Check to see if this is the *first* block we've seen
271                     // If so, buffer it and return null zero bytes
272                     if (m_depadBuffer == null) {
273                         m_depadBuffer = new byte[InputBlockSize];
274                         // copy the last InputBlockSize bytes to m_depadBuffer everything else gets processed and returned
275                         int inputToProcess = inputCount - InputBlockSize;
276                         Buffer.InternalBlockCopy(inputBuffer, inputOffset+inputToProcess, m_depadBuffer, 0, InputBlockSize);
277                         return DecryptData(inputBuffer,
278                                            inputOffset,
279                                            inputToProcess,
280                                            ref outputBuffer,
281                                            outputOffset,
282                                            m_paddingValue,
283                                            false);
284                     } else {
285                         // we already have a depad buffer, so we need to decrypt that info first & copy it out
286                         int r = DecryptData(m_depadBuffer,
287                                             0, m_depadBuffer.Length,
288                                             ref outputBuffer,
289                                             outputOffset,
290                                             m_paddingValue,
291                                             false);
292                         outputOffset += OutputBlockSize;
293                         int inputToProcess = inputCount - InputBlockSize;
294                         Buffer.InternalBlockCopy(inputBuffer, inputOffset+inputToProcess, m_depadBuffer, 0, InputBlockSize);
295                         r = DecryptData(inputBuffer,
296                                         inputOffset,
297                                         inputToProcess,
298                                         ref outputBuffer,
299                                         outputOffset,
300                                         m_paddingValue,
301                                         false);
302                         return (OutputBlockSize + r);
303                     }
304 #if FEATURE_CRYPTO
305                 }
306 #endif // FEATURE_CRYPTO
307             }
308         }
309
310         public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { 
311             if (inputBuffer == null) throw new ArgumentNullException("inputBuffer");
312             if (inputOffset < 0) throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
313             if (inputCount < 0 || (inputCount > inputBuffer.Length)) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
314             if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
315             Contract.EndContractBlock();
316
317             if (m_transformMode == RijndaelManagedTransformMode.Encrypt) {
318                 // If we're encrypting we can alway return what we compute because there's no m_depadBuffer
319                 byte[] transformedBytes = null;
320                 EncryptData(inputBuffer,
321                             inputOffset,
322                             inputCount,
323                             ref transformedBytes,
324                             0,
325                             m_paddingValue,
326                             true);
327                 Reset();
328                 return transformedBytes;
329             } 
330             else {
331                 if (inputCount%InputBlockSize != 0)
332                     throw new CryptographicException(Environment.GetResourceString("Cryptography_SSD_InvalidDataSize"));
333
334                 if (m_depadBuffer == null) {
335                     byte[] transformedBytes = null;
336                     DecryptData(inputBuffer,
337                                 inputOffset,
338                                 inputCount,
339                                 ref transformedBytes,
340                                 0,
341                                 m_paddingValue,
342                                 true);
343                     Reset();
344                     return transformedBytes;
345                 } else {
346                     byte[] temp = new byte[m_depadBuffer.Length + inputCount];
347                     Buffer.InternalBlockCopy(m_depadBuffer, 0, temp, 0, m_depadBuffer.Length);
348                     Buffer.InternalBlockCopy(inputBuffer, inputOffset, temp, m_depadBuffer.Length, inputCount);
349                     byte[] transformedBytes = null;
350                     DecryptData(temp,
351                                 0,
352                                 temp.Length,
353                                 ref transformedBytes,
354                                 0,
355                                 m_paddingValue,
356                                 true);
357                     Reset();
358                     return transformedBytes;
359                 }
360             }
361         }
362
363         //
364         // resets the state of the transform
365         //
366
367         public void Reset() {
368             m_depadBuffer = null;
369 #if FEATURE_CRYPTO // see code:System.Security.Cryptography.RijndaelManaged#CoreCLRRijndaelModes
370             if (m_cipherMode == CipherMode.CBC)
371 #endif // FEATURE_CRYPTO
372                 Buffer.InternalBlockCopy(m_IV, 0, m_lastBlockBuffer, 0, m_blockSizeBytes);
373 #if FEATURE_CRYPTO
374             if (m_cipherMode == CipherMode.CFB)
375                 Buffer.InternalBlockCopy(m_IV, 0, m_shiftRegister, 0, 4*m_Nb);
376 #endif // FEATURE_CRYPTO
377         }
378
379         //
380         // Deals with the various cipher and padding modes and calls the AES encryption routine.
381         // This method writes the encrypted data into the output buffer. If the output buffer is null,
382         // it allocates it and populates it with the encrypted data.
383         //
384         [SecuritySafeCritical]
385         private unsafe int EncryptData(byte[] inputBuffer,
386                                        int inputOffset,
387                                        int inputCount,
388                                        ref byte[] outputBuffer,
389                                        int outputOffset,
390                                        PaddingMode paddingMode,
391                                        bool fLast) {
392             if (inputBuffer.Length < inputOffset + inputCount)
393                 throw new CryptographicException(Environment.GetResourceString("Cryptography_InsufficientBuffer"));
394
395             int padSize = 0;
396             int lonelyBytes = inputCount % m_inputBlockSize;
397
398             // Check the padding mode and make sure we have enough outputBuffer to handle any padding we have to do.
399             byte[] padBytes = null;
400             int workBaseIndex = inputOffset, index = 0;
401             if (fLast) {
402 #if FEATURE_CRYPTO // see code:System.Security.Cryptography.RijndaelManaged#CoreCLRRijndaelModes
403                 switch (paddingMode) {
404                 case PaddingMode.None:
405                     if (lonelyBytes != 0)
406                         throw new CryptographicException(Environment.GetResourceString("Cryptography_SSE_InvalidDataSize"));
407                     break;
408                 case PaddingMode.Zeros:
409                     if (lonelyBytes != 0)
410                         padSize = m_inputBlockSize - lonelyBytes;
411                     break;
412                 case PaddingMode.PKCS7:
413 #endif // FEATURE_CRYPTO
414                     padSize = m_inputBlockSize - lonelyBytes;
415
416 #if FEATURE_CRYPTO
417                     break;
418                 case PaddingMode.ANSIX923:
419                     padSize = m_inputBlockSize - lonelyBytes;
420                     break;
421                 case PaddingMode.ISO10126:
422                     padSize = m_inputBlockSize - lonelyBytes;
423                     break;
424                 }
425 #endif // FEATURE_CRYPTO
426
427                 if (padSize != 0) {
428                     padBytes = new byte[padSize];
429 #if FEATURE_CRYPTO
430                     switch (paddingMode) {
431                     case PaddingMode.None:
432                         break;
433                     case PaddingMode.Zeros:
434                         // padBytes is already initialized with zeros
435                         break;
436                     case PaddingMode.PKCS7:
437 #endif // FEATURE_CRYPTO
438                         for (index = 0; index < padSize; index++)
439                             padBytes[index] = (byte) padSize;
440
441 #if FEATURE_CRYPTO
442                         break;
443                     case PaddingMode.ANSIX923:
444                         // padBytes is already initialized with zeros. Simply change the last byte.
445                         padBytes[padSize - 1] = (byte) padSize;
446                         break;
447                     case PaddingMode.ISO10126:
448                         // generate random bytes
449                         Utils.StaticRandomNumberGenerator.GetBytes(padBytes);
450                         padBytes[padSize - 1] = (byte) padSize;
451                         break;
452                     }
453 #endif // FEATURE_CRYPTO
454                 }
455             }
456
457             if (outputBuffer == null) {
458                 outputBuffer = new byte[inputCount + padSize];
459                 outputOffset = 0;
460             } else {
461                 if ((outputBuffer.Length - outputOffset) < (inputCount + padSize))
462                     throw new CryptographicException(Environment.GetResourceString("Cryptography_InsufficientBuffer"));
463             }
464
465             fixed (int* encryptindex = m_encryptindex) {
466                 fixed (int* encryptKeyExpansion = m_encryptKeyExpansion) {
467                     fixed (int *T = s_T) {
468                         fixed (int *TF = s_TF) {
469                             int* work = stackalloc int[m_Nb];
470                             int* temp = stackalloc int[m_Nb];
471
472                             int iNumBlocks = (inputCount + padSize) / m_inputBlockSize;
473                             int transformCount = outputOffset;
474                             for (int blockNum = 0;  blockNum < iNumBlocks; ++blockNum) {
475 #if FEATURE_CRYPTO // see code:System.Security.Cryptography.RijndaelManaged#CoreCLRRijndaelModes
476                                 if (m_cipherMode == CipherMode.CFB) {
477                                     Contract.Assert(m_blockSizeBytes <= m_Nb * sizeof(int), "m_blockSizeBytes <= m_Nb * sizeof(int)");
478                                     Buffer.Memcpy((byte *)work, 0, m_shiftRegister, 0, m_blockSizeBytes);
479                                 } else {
480 #endif // FEATURE_CRYPTO
481                                                                                            if (blockNum != iNumBlocks - 1 || padSize == 0) {
482                                         Contract.Assert(m_blockSizeBytes <= m_Nb * sizeof(int), "m_blockSizeBytes <= m_Nb * sizeof(int)");
483                                         Buffer.Memcpy((byte*)work, 0, inputBuffer, workBaseIndex, m_blockSizeBytes);
484                                     } else {
485                                         int padIndex = 0;
486                                         index = workBaseIndex;
487                                         for (int i = 0; i < m_Nb; ++i) {
488                                             int i0 = (index >= workBaseIndex + lonelyBytes) ? padBytes[padIndex++] : inputBuffer[index++];
489                                             int i1 = (index >= workBaseIndex + lonelyBytes) ? padBytes[padIndex++] : inputBuffer[index++];
490                                             int i2 = (index >= workBaseIndex + lonelyBytes) ? padBytes[padIndex++] : inputBuffer[index++];
491                                             int i3 = (index >= workBaseIndex + lonelyBytes) ? padBytes[padIndex++] : inputBuffer[index++];
492                                             work[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0;
493                                         }
494                                     }
495 #if FEATURE_CRYPTO
496                                 }
497 #endif // FEATURE_CRYPTO
498
499 #if FEATURE_CRYPTO
500                                 if (m_cipherMode == CipherMode.CBC) {
501 #endif // FEATURE_CRYPTO
502                                     for (int i = 0; i < m_Nb; ++i) {
503                                         // XOR with the last encrypted block
504                                         work[i] ^= m_lastBlockBuffer[i];
505                                     }
506 #if FEATURE_CRYPTO
507                                 }
508 #endif // FEATURE_CRYPTO
509
510                                 Enc(encryptindex, encryptKeyExpansion, T, TF, work, temp);
511
512 #if FEATURE_CRYPTO
513                                 if (m_cipherMode == CipherMode.CFB) {
514                                     index = workBaseIndex;
515                                     if (blockNum != iNumBlocks - 1 || padSize == 0) {
516                                         for (int i = 0; i < m_Nb; ++i) {
517                                             if (index >= workBaseIndex + m_inputBlockSize) break;
518                                             outputBuffer[transformCount++] = (byte)((temp[i]       & 0xFF) ^ inputBuffer[index++]);
519                                             if (index >= workBaseIndex + m_inputBlockSize) break;
520                                             outputBuffer[transformCount++] = (byte)((temp[i] >> 8  & 0xFF) ^ inputBuffer[index++]);
521                                             if (index >= workBaseIndex + m_inputBlockSize) break;
522                                             outputBuffer[transformCount++] = (byte)((temp[i] >> 16 & 0xFF) ^ inputBuffer[index++]);
523                                             if (index >= workBaseIndex + m_inputBlockSize) break;
524                                             outputBuffer[transformCount++] = (byte)((temp[i] >> 24 & 0xFF) ^ inputBuffer[index++]);
525                                         }
526                                     } else {
527                                         byte[] tmpInputBuffer = new byte[m_inputBlockSize];
528                                         Buffer.InternalBlockCopy(inputBuffer, workBaseIndex, tmpInputBuffer, 0, lonelyBytes);
529                                         Buffer.InternalBlockCopy(padBytes, 0, tmpInputBuffer, lonelyBytes, padSize);
530                                         index = 0;
531                                         for (int i = 0; i < m_Nb; ++i) {
532                                             if (index >= m_inputBlockSize) break;
533                                             outputBuffer[transformCount++] = (byte)((temp[i]       & 0xFF) ^ tmpInputBuffer[index++]);
534                                             if (index >= m_inputBlockSize) break;
535                                             outputBuffer[transformCount++] = (byte)((temp[i] >> 8  & 0xFF) ^ tmpInputBuffer[index++]);
536                                             if (index >= m_inputBlockSize) break;
537                                             outputBuffer[transformCount++] = (byte)((temp[i] >> 16 & 0xFF) ^ tmpInputBuffer[index++]);
538                                             if (index >= m_inputBlockSize) break;
539                                             outputBuffer[transformCount++] = (byte)((temp[i] >> 24 & 0xFF) ^ tmpInputBuffer[index++]);
540                                         }
541                                     }
542                                     // shift m_lastBlockBuffer to the left by m_inputBlockSize bytes.
543                                     index = 0;
544                                     while (index < m_blockSizeBytes - m_inputBlockSize) {
545                                         m_shiftRegister[index] = m_shiftRegister[index + m_inputBlockSize];
546                                         index++;
547                                     }
548                                     Buffer.InternalBlockCopy(outputBuffer, blockNum * m_inputBlockSize, m_shiftRegister, m_blockSizeBytes - m_inputBlockSize, m_inputBlockSize);
549                                 } else {
550 #endif // FEATURE_CRYPTO
551                                     for (int i = 0; i < m_Nb; ++i) {
552                                         outputBuffer[transformCount++] = (byte)(temp[i]       & 0xFF);
553                                         outputBuffer[transformCount++] = (byte)(temp[i] >> 8  & 0xFF);
554                                         outputBuffer[transformCount++] = (byte)(temp[i] >> 16 & 0xFF);
555                                         outputBuffer[transformCount++] = (byte)(temp[i] >> 24 & 0xFF);
556                                     }
557
558 #if FEATURE_CRYPTO
559                                     if (m_cipherMode == CipherMode.CBC) {
560 #endif // FEATURE_CRYPTO
561                                         fixed (int* pLastBlockBuffer = m_lastBlockBuffer) {
562                                             Contract.Assert(m_blockSizeBytes <= m_lastBlockBuffer.Length * sizeof(int), "m_blockSizeBytes <= m_lastBlockBuffer.Length * sizeof(int)");
563                                             Buffer.Memcpy((byte*)pLastBlockBuffer, (byte*)temp, m_blockSizeBytes);
564                                         }
565 #if FEATURE_CRYPTO
566                                     }
567                                 }
568 #endif // FEATURE_CRYPTO
569                                 workBaseIndex += m_inputBlockSize;
570                             }
571                         }
572                     }
573                 }
574             }
575
576             return (inputCount + padSize);
577         }
578
579         //
580         // Deals with the various cipher and padding modes and calls the AES decryption routine.
581         // This method writes the decrypted data into the output buffer. If the output buffer is null,
582         // it allocates it and populates it with the decrypted data.
583         //
584
585         [System.Security.SecuritySafeCritical]  // auto-generated
586         private unsafe int DecryptData(byte[] inputBuffer,
587                                        int inputOffset,
588                                        int inputCount,
589                                        ref byte[] outputBuffer,
590                                        int outputOffset,
591                                        PaddingMode paddingMode,
592                                        bool fLast) {
593             if (inputBuffer.Length < inputOffset + inputCount)
594                 throw new CryptographicException(Environment.GetResourceString("Cryptography_InsufficientBuffer"));
595
596             if (outputBuffer == null) {
597                 outputBuffer = new byte[inputCount];
598                 outputOffset = 0;
599             } else {
600                 if ((outputBuffer.Length - outputOffset) < inputCount)
601                     throw new CryptographicException(Environment.GetResourceString("Cryptography_InsufficientBuffer"));
602             }
603
604             fixed (int* encryptindex = m_encryptindex) {
605                 fixed (int* encryptKeyExpansion = m_encryptKeyExpansion) {
606                     fixed (int* decryptindex = m_decryptindex) {
607                         fixed (int* decryptKeyExpansion = m_decryptKeyExpansion) {
608                             fixed (int *T = s_T) {
609                                 fixed (int *TF = s_TF) {
610                                     fixed (int *iT = s_iT) {
611                                         fixed (int *iTF = s_iTF) {
612                                             int* work = stackalloc int[m_Nb];
613                                             int* temp = stackalloc int[m_Nb];
614
615                                             int iNumBlocks = inputCount / m_inputBlockSize;
616                                             int workBaseIndex = inputOffset, index = 0, transformCount = outputOffset;
617                                             for (int blockNum = 0; blockNum < iNumBlocks; ++blockNum) {
618 #if FEATURE_CRYPTO // see code:System.Security.Cryptography.RijndaelManaged#CoreCLRRijndaelModes
619                                                 if (m_cipherMode == CipherMode.CFB) {
620                                                     index = 0;
621                                                     for (int i = 0; i < m_Nb; ++i) {
622                                                         int i0 = m_shiftRegister[index++];
623                                                         int i1 = m_shiftRegister[index++];
624                                                         int i2 = m_shiftRegister[index++];
625                                                         int i3 = m_shiftRegister[index++];
626                                                         work[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0;
627                                                     }
628                                                 } else {
629 #endif // FEATURE_CRYPTO
630                                                     index = workBaseIndex;
631                                                     for (int i = 0; i < m_Nb; ++i) {
632                                                         int i0 = inputBuffer[index++];
633                                                         int i1 = inputBuffer[index++];
634                                                         int i2 = inputBuffer[index++];
635                                                         int i3 = inputBuffer[index++];
636                                                         work[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0;
637                                                     }
638 #if FEATURE_CRYPTO
639                                                 }
640 #endif // FEATURE_CRYPTO
641
642 #if FEATURE_CRYPTO
643                                                 if (m_cipherMode == CipherMode.CFB) {
644                                                     // We use the encryption function in both encryption and decryption in CFB mode.
645                                                     Enc(encryptindex, encryptKeyExpansion, T, TF, work, temp);
646
647                                                     index = workBaseIndex;
648                                                     for (int i = 0; i < m_Nb; ++i) {
649                                                         if (index >= workBaseIndex + m_inputBlockSize) break;
650                                                         outputBuffer[transformCount++] = (byte)((temp[i]       & 0xFF) ^ inputBuffer[index++]);
651                                                         if (index >= workBaseIndex + m_inputBlockSize) break;
652                                                         outputBuffer[transformCount++] = (byte)((temp[i] >> 8  & 0xFF) ^ inputBuffer[index++]);
653                                                         if (index >= workBaseIndex + m_inputBlockSize) break;
654                                                         outputBuffer[transformCount++] = (byte)((temp[i] >> 16 & 0xFF) ^ inputBuffer[index++]);
655                                                         if (index >= workBaseIndex + m_inputBlockSize) break;
656                                                         outputBuffer[transformCount++] = (byte)((temp[i] >> 24 & 0xFF) ^ inputBuffer[index++]);
657                                                     }
658                                                     // shift m_lastBlockBuffer to the left by m_inputBlockSize bytes.
659                                                     index = 0;
660                                                     while (index < m_blockSizeBytes - m_inputBlockSize) {
661                                                         m_shiftRegister[index] = m_shiftRegister[index + m_inputBlockSize];
662                                                         index++;
663                                                     }
664                                                     Buffer.InternalBlockCopy(inputBuffer, workBaseIndex, m_shiftRegister, m_blockSizeBytes - m_inputBlockSize, m_inputBlockSize);
665                                                 } else {
666 #endif // FEATURE_CRYPTO
667                                                     Dec(decryptindex, decryptKeyExpansion, iT, iTF, work, temp);
668
669 #if FEATURE_CRYPTO
670                                                     if (m_cipherMode == CipherMode.CBC) {
671 #endif // FEATURE_CRYPTO
672                                                         index = workBaseIndex;
673                                                         for (int i = 0; i < m_Nb; ++i) {
674                                                             temp[i] ^= m_lastBlockBuffer[i];
675                                                             // save the input buffer
676                                                             int i0 = inputBuffer[index++];
677                                                             int i1 = inputBuffer[index++];
678                                                             int i2 = inputBuffer[index++];
679                                                             int i3 = inputBuffer[index++];
680                                                             m_lastBlockBuffer[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0;
681                                                         }
682 #if FEATURE_CRYPTO
683                                                     }
684 #endif // FEATURE_CRYPTO
685
686                                                     for (int i = 0; i < m_Nb; ++i) {
687                                                         outputBuffer[transformCount++] = (byte)(temp[i]       & 0xFF);
688                                                         outputBuffer[transformCount++] = (byte)(temp[i] >> 8  & 0xFF);
689                                                         outputBuffer[transformCount++] = (byte)(temp[i] >> 16 & 0xFF);
690                                                         outputBuffer[transformCount++] = (byte)(temp[i] >> 24 & 0xFF);
691                                                     }
692 #if FEATURE_CRYPTO
693                                                 }
694 #endif // FEATURE_CRYPTO
695
696                                                 workBaseIndex += m_inputBlockSize;
697                                             }
698
699                                             if (fLast == false)
700                                                 return inputCount;
701
702                                             // this is the last block, remove the padding.
703                                             byte[] outputBuffer1 = outputBuffer;
704                                             int padSize = 0;
705 #if FEATURE_CRYPTO // see code:System.Security.Cryptography.RijndaelManaged#CoreCLRRijndaelModes
706                                             switch (paddingMode) {
707                                             case PaddingMode.None:
708                                                 break;
709                                             case PaddingMode.Zeros:
710                                                 break;
711                                             case PaddingMode.PKCS7:
712 #endif // FEATURE_CRYPTO
713                                                 if (inputCount == 0)
714                                                     throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding"));
715                                                 padSize = outputBuffer[inputCount - 1];
716                                                 if (padSize > outputBuffer.Length || padSize > InputBlockSize || padSize <= 0)
717                                                     throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding"));
718                                                 for (index = 1; index <= padSize; index++) 
719                                                     if (outputBuffer[inputCount - index] != padSize)
720                                                         throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding"));
721                                                 outputBuffer1 = new byte[outputBuffer.Length - padSize];
722                                                 Buffer.InternalBlockCopy(outputBuffer, 0, outputBuffer1, 0, outputBuffer.Length - padSize);
723 #if FEATURE_CRYPTO
724                                                 break;
725                                             case PaddingMode.ANSIX923:
726                                                 if (inputCount == 0)
727                                                     throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding"));
728                                                 padSize = outputBuffer[inputCount - 1];
729                                                 if (padSize > outputBuffer.Length || padSize > InputBlockSize || padSize <= 0)
730                                                     throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding"));
731                                                 // check the validity of the padding
732                                                 for (index = 2; index <= padSize; index++) 
733                                                     if (outputBuffer[inputCount - index] != 0)
734                                                         throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding"));
735                                                 outputBuffer1 = new byte[outputBuffer.Length - padSize];
736                                                 Buffer.InternalBlockCopy(outputBuffer, 0, outputBuffer1, 0, outputBuffer.Length - padSize);
737                                                 break;
738                                             case PaddingMode.ISO10126:
739                                                 if (inputCount == 0)
740                                                     throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding"));
741                                                 padSize = outputBuffer[inputCount - 1];
742                                                 if (padSize > outputBuffer.Length || padSize > InputBlockSize || padSize <= 0)
743                                                     throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding"));
744                                                 // Just ignore the random bytes
745                                                 outputBuffer1 = new byte[outputBuffer.Length - padSize];
746                                                 Buffer.InternalBlockCopy(outputBuffer, 0, outputBuffer1, 0, outputBuffer.Length - padSize);
747                                                 break;
748                                             }
749 #endif // FEATURE_CRYPTO
750                                             outputBuffer = outputBuffer1;
751                                             return outputBuffer1.Length;
752                                         }
753                                     }
754                                 }
755                             }
756                         }
757                     }
758                 }
759             }
760         }
761
762         //
763         // AES encryption function.
764         //
765         [System.Security.SecurityCritical]  // auto-generated
766         private unsafe void Enc(int* encryptindex, int* encryptKeyExpansion, int* T, int* TF, int* work, int* temp) {
767             for (int i = 0; i < m_Nb; ++i) {
768                 work[i] ^= encryptKeyExpansion[i];
769             }
770
771             int* _encryptindex;
772             int* _encryptKeyExpansion = &encryptKeyExpansion[m_Nb];
773             for (int r = 1; r < m_Nr; ++r) {
774                 _encryptindex = encryptindex;
775                 for (int i = 0; i < m_Nb; ++i) {
776                     temp[i] = T[0 + (work[i] & 0xFF)] ^
777                               T[256 + ((work[_encryptindex[0]] >> 8) & 0xFF)] ^
778                               T[512 + ((work[_encryptindex[m_Nb]] >> 16) & 0xFF)] ^
779                               T[768 + ((work[_encryptindex[m_Nb * 2]] >> 24) & 0xFF)] ^
780                               *_encryptKeyExpansion;
781                     _encryptindex++;
782                     _encryptKeyExpansion++;
783                 }
784
785                 for (int i = 0; i < m_Nb; ++i) {
786                     work[i] = temp[i];
787                 }
788             }
789
790             _encryptindex = encryptindex;
791             for (int i = 0; i < m_Nb; ++i) {
792                 temp[i] = TF[0 + (work[i] & 0xFF)] ^
793                           TF[256 + ((work[_encryptindex[0]] >> 8) & 0xFF)] ^
794                           TF[512 + ((work[_encryptindex[m_Nb]] >> 16) & 0xFF)] ^
795                           TF[768 + ((work[_encryptindex[m_Nb * 2]] >> 24) & 0xFF)] ^
796                           *_encryptKeyExpansion;
797                 _encryptindex++;
798                 _encryptKeyExpansion++;
799             }
800         }
801
802         //
803         // AES decryption function.
804         //
805
806         [System.Security.SecurityCritical]  // auto-generated
807         unsafe private void Dec (int *decryptindex, int *decryptKeyExpansion, int *iT, int *iTF, int *work, int *temp) {
808             int keyIndex = m_Nb * m_Nr;
809             for (int i = 0; i < m_Nb; ++i) {
810                 work[i] ^= decryptKeyExpansion[keyIndex];
811                 keyIndex++;
812             }
813
814             int* _decryptindex;
815             int* _decryptKeyExpansion;
816             for (int r = 1; r < m_Nr; ++r) {
817                 keyIndex -= 2 * m_Nb;
818                 _decryptindex = decryptindex;
819                 _decryptKeyExpansion = &decryptKeyExpansion[keyIndex];
820                 for (int i = 0; i < m_Nb; ++i) {
821                     temp[i] = iT[0 + ((work[i]) & 0xFF)] ^
822                               iT[256 + ((work[_decryptindex[0]] >> 8) & 0xFF)] ^
823                               iT[512 + ((work[_decryptindex[m_Nb]] >> 16) & 0xFF)] ^
824                               iT[768 + ((work[_decryptindex[m_Nb * 2]] >> 24) & 0xFF)] ^
825                               *_decryptKeyExpansion;
826                     keyIndex++;
827                     _decryptindex++;
828                     _decryptKeyExpansion++;
829                 }
830                 for (int i = 0; i < m_Nb; ++i) {
831                     work[i] = temp[i];
832                 }
833             }
834
835             keyIndex = 0;
836             _decryptindex = decryptindex;
837             _decryptKeyExpansion = &decryptKeyExpansion[keyIndex];
838             for (int i = 0; i < m_Nb; ++i) {
839                 temp[i] = iTF[0 + ((work[i]) & 0xFF)] ^
840                           iTF[256 + ((work[_decryptindex[0]] >> 8) & 0xFF)] ^
841                           iTF[512 + ((work[_decryptindex[m_Nb]] >> 16) & 0xFF)] ^
842                           iTF[768 + ((work[_decryptindex[m_Nb * 2]] >> 24) & 0xFF)] ^
843                           *_decryptKeyExpansion;
844                 _decryptindex++;
845                 _decryptKeyExpansion++;
846             }
847         }
848
849         //
850         // Key expansion routine.
851         //
852
853         private void GenerateKeyExpansion(byte[] rgbKey) {
854             switch (m_blockSizeBits > rgbKey.Length * 8 ? m_blockSizeBits : rgbKey.Length * 8) {
855             case 128:
856                 m_Nr = 10;
857                 break;
858
859             case 192:
860                 m_Nr = 12;
861                 break;
862
863             case 256:
864                 m_Nr = 14;
865                 break;
866
867             default:
868                 throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
869             }
870
871             m_encryptKeyExpansion = new int[m_Nb * (m_Nr + 1)];
872             m_decryptKeyExpansion = new int[m_Nb * (m_Nr + 1)];
873             int iTemp;
874
875             int index = 0;
876             for (int i = 0; i < m_Nk; ++i) {
877                 int i0 = rgbKey[index++];
878                 int i1 = rgbKey[index++];
879                 int i2 = rgbKey[index++];
880                 int i3 = rgbKey[index++];
881                 m_encryptKeyExpansion[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0;
882             }
883
884             if (m_Nk <= 6) {
885                 for (int i = m_Nk; i < m_Nb * (m_Nr + 1); ++i) {
886                     iTemp = m_encryptKeyExpansion[i-1];
887
888                     if (i % m_Nk == 0) {
889                         iTemp = SubWord(rot3(iTemp));
890                         iTemp = iTemp ^ s_Rcon[(i / m_Nk) - 1];
891                     }
892
893                     m_encryptKeyExpansion[i] = m_encryptKeyExpansion[i - m_Nk] ^ iTemp;
894                 }
895             } else {
896                 for (int i = m_Nk; i < m_Nb * (m_Nr + 1); ++i) {
897                     iTemp = m_encryptKeyExpansion[i-1];
898
899                     if (i % m_Nk == 0) {
900                         iTemp = SubWord(rot3(iTemp));
901                         iTemp = iTemp ^ s_Rcon[(i / m_Nk) - 1];
902                     }
903                     else if (i % m_Nk == 4) {
904                         iTemp = SubWord(iTemp);
905                     }
906
907                     m_encryptKeyExpansion[i] = m_encryptKeyExpansion[i - m_Nk] ^ iTemp;
908                 }
909             }
910
911             for (int i = 0; i < m_Nb; ++i) {
912                 m_decryptKeyExpansion[i] = m_encryptKeyExpansion[i];
913                 m_decryptKeyExpansion[m_Nb * m_Nr + i] = m_encryptKeyExpansion[m_Nb * m_Nr + i];
914             }
915
916             for (int i = m_Nb; i < m_Nb * m_Nr; ++i) {
917                 int key = m_encryptKeyExpansion[i];
918                 int mul02 = MulX(key);
919                 int mul04 = MulX(mul02);
920                 int mul08 = MulX(mul04);
921                 int mul09 = key ^ mul08;
922                 m_decryptKeyExpansion[i] = mul02 ^ mul04 ^ mul08 ^ rot3(mul02 ^ mul09) ^ rot2(mul04 ^ mul09) ^ rot1(mul09);
923             }
924         }
925
926         private static int rot1(int val) {
927             return (val << 8  & unchecked((int)0xFFFFFF00)) | (val >> 24 & unchecked((int)0x000000FF));
928         }
929
930         private static int rot2(int val) {
931             return (val << 16 & unchecked((int)0xFFFF0000)) | (val >> 16 & unchecked((int)0x0000FFFF));
932         }
933
934         private static int rot3(int val) {
935             return (val << 24 & unchecked((int)0xFF000000)) | (val >> 8  & unchecked((int)0x00FFFFFF));
936         }
937
938         private static int SubWord(int a) {
939             return s_Sbox[a       & 0xFF]       |
940                    s_Sbox[a >> 8  & 0xFF] << 8  |
941                    s_Sbox[a >> 16 & 0xFF] << 16 |
942                    s_Sbox[a >> 24 & 0xFF] << 24;
943         }
944
945         private static int MulX(int x) {
946             int    u = x & unchecked((int)0x80808080);
947             return ((x & unchecked((int)0x7f7f7f7f)) << 1) ^ ((u - (u >> 7 & 0x01FFFFFF)) & 0x1b1b1b1b);
948         }
949
950         private static readonly byte[] s_Sbox = new byte[] {
951              99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118, 
952             202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 
953             183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21, 
954               4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117, 
955               9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132, 
956              83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 
957             208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168, 
958              81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, 
959             205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115, 
960              96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 
961             224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 
962             231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 
963             186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 
964             112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 
965             225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223, 
966             140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22 };
967
968         private static readonly int[] s_Rcon = new int[] {
969             0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36,
970             0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6,
971             0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 };
972
973         private static readonly int[] s_T = new int[4 * 256]
974             {
975                 // s_T1
976                 -1520213050,  -2072216328,  -1720223762,  -1921287178,    234025727,  -1117033514,  -1318096930,   1422247313, 
977                 1345335392,     50397442,  -1452841010,   2099981142,    436141799,   1658312629,   -424957107,  -1703512340, 
978                 1170918031,  -1652391393,   1086966153,  -2021818886,    368769775,   -346465870,   -918075506,    200339707, 
979                 -324162239,   1742001331,    -39673249,   -357585083,  -1080255453,   -140204973,  -1770884380,   1539358875, 
980                -1028147339,    486407649,  -1366060227,   1780885068,   1513502316,   1094664062,     49805301,   1338821763, 
981                 1546925160,   -190470831,    887481809,    150073849,  -1821281822,   1943591083,   1395732834,   1058346282, 
982                  201589768,   1388824469,   1696801606,   1589887901,    672667696,  -1583966665,    251987210,  -1248159185, 
983                  151455502,    907153956,  -1686077413,   1038279391,    652995533,   1764173646,   -843926913,  -1619692054, 
984                  453576978,  -1635548387,   1949051992,    773462580,    756751158,  -1301385508,   -296068428,    -73359269, 
985                 -162377052,   1295727478,   1641469623,   -827083907,   2066295122,   1055122397,   1898917726,  -1752923117, 
986                 -179088474,   1758581177,            0,    753790401,   1612718144,    536673507,   -927878791,   -312779850, 
987                -1100322092,   1187761037,   -641810841,   1262041458,   -565556588,   -733197160,   -396863312,   1255133061, 
988                 1808847035,    720367557,   -441800113,    385612781,   -985447546,   -682799718,   1429418854,  -1803188975, 
989                 -817543798,    284817897,    100794884,  -2122350594,   -263171936,   1144798328,  -1163944155,   -475486133, 
990                 -212774494,    -22830243,  -1069531008,  -1970303227,  -1382903233,  -1130521311,   1211644016,     83228145, 
991                 -541279133,  -1044990345,   1977277103,   1663115586,    806359072,    452984805,    250868733,   1842533055, 
992                 1288555905,    336333848,    890442534,    804056259,   -513843266,  -1567123659,   -867941240,    957814574, 
993                 1472513171,   -223893675,  -2105639172,   1195195770,  -1402706744,   -413311558,    723065138,  -1787595802, 
994                -1604296512,  -1736343271,   -783331426,   2145180835,   1713513028,   2116692564,  -1416589253,  -2088204277, 
995                 -901364084,    703524551,   -742868885,   1007948840,   2044649127,   -497131844,    487262998,   1994120109, 
996                 1004593371,   1446130276,   1312438900,    503974420,   -615954030,    168166924,   1814307912,   -463709000, 
997                 1573044895,   1859376061,   -273896381,  -1503501628,  -1466855111,  -1533700815,    937747667,  -1954973198, 
998                  854058965,   1137232011,   1496790894,  -1217565222,  -1936880383,   1691735473,   -766620004,   -525751991, 
999                -1267962664,    -95005012,    133494003,    636152527,  -1352309302,  -1904575756,   -374428089,    403179536, 
1000                 -709182865,  -2005370640,   1864705354,   1915629148,    605822008,   -240736681,   -944458637,   1371981463, 
1001                  602466507,   2094914977,  -1670089496,    555687742,   -582268010,   -591544991,  -2037675251,  -2054518257, 
1002                -1871679264,   1111375484,   -994724495,  -1436129588,   -666351472,     84083462,     32962295,    302911004, 
1003                -1553899070,   1597322602,   -111716434,   -793134743,  -1853454825,   1489093017,    656219450,  -1180787161, 
1004                  954327513,    335083755,  -1281845205,    856756514,  -1150719534,   1893325225,  -1987146233,  -1483434957, 
1005                -1231316179,    572399164,  -1836611819,    552200649,   1238290055,    -11184726,   2015897680,   2061492133, 
1006                -1886614525,   -123625127,  -2138470135,    386731290,   -624967835,    837215959,   -968736124,  -1201116976, 
1007                -1019133566,  -1332111063,   1999449434,    286199582,   -877612933,    -61582168,   -692339859,    974525996, 
1008
1009                 // s_T2
1010                1667483301,   2088564868,   2004348569,   2071721613,   -218956019,   1802229437,   1869602481,   -976907948, 
1011                  808476752,     16843267,   1734856361,    724260477,    -16849127,   -673729182,  -1414836762,   1987505306, 
1012                 -892694715,  -2105401443,   -909539008,   2105408135,    -84218091,   1499050731,   1195871945,   -252642549, 
1013                -1381154324,   -724257945,  -1566416899,  -1347467798,  -1667488833,  -1532734473,   1920132246,  -1061119141, 
1014                -1212713534,    -33693412,  -1819066962,    640044138,    909536346,   1061125697,   -134744830,   -859012273, 
1015                  875849820,  -1515892236,   -437923532,   -235800312,   1903288979,   -656888973,    825320019,    353708607, 
1016                   67373068,   -943221422,    589514341,  -1010590370,    404238376,  -1768540255,     84216335,  -1701171275, 
1017                  117902857,    303178806,  -2139087973,   -488448195,   -336868058,    656887401,  -1296924723,   1970662047, 
1018                  151589403,  -2088559202,    741103732,    437924910,    454768173,   1852759218,   1515893998,  -1600103429, 
1019                 1381147894,    993752653,   -690571423,  -1280082482,    690573947,   -471605954,    791633521,  -2071719017, 
1020                 1397991157,   -774784664,            0,   -303185620,    538984544,    -50535649,  -1313769016,   1532737261, 
1021                 1785386174,   -875852474,  -1094817831,    960066123,   1246401758,   1280088276,   1482207464,   -808483510, 
1022                 -791626901,   -269499094,  -1431679003,    -67375850,   1128498885,   1296931543,    859006549,  -2054876780, 
1023                 1162185423,   -101062384,     33686534,   2139094657,   1347461360,   1010595908,  -1616960070,  -1465365533, 
1024                 1364304627,  -1549574658,   1077969088,  -1886452342,  -1835909203,  -1650646596,    943222856,   -168431356, 
1025                -1128504353,  -1229555775,   -623202443,    555827811,    269492272,        -6886,   -202113778,   -757940371, 
1026                 -842170036,    202119188,    320022069,   -320027857,   1600110305,  -1751698014,   1145342156,    387395129, 
1027                 -993750185,  -1482205710,   2122251394,   1027439175,   1684326572,   1566423783,    421081643,   1936975509, 
1028                 1616953504,  -2122245736,   1330618065,   -589520001,    572671078,    707417214,  -1869595733,  -2004350077, 
1029                 1179028682,   -286341335,  -1195873325,    336865340,   -555833479,   1583267042,    185275933,   -606360202, 
1030                 -522134725,    842163286,    976909390,    168432670,   1229558491,    101059594,    606357612,   1549580516, 
1031                -1027432611,   -741098130,  -1397996561,   1650640038,  -1852753496,  -1785384540,   -454765769,   2038035083, 
1032                 -404237006,   -926381245,    926379609,   1835915959,  -1920138868,   -707415708,   1313774802,  -1448523296, 
1033                 1819072692,   1448520954,   -185273593,   -353710299,   1701169839,   2054878350,  -1364310039,    134746136, 
1034                -1162186795,   2021191816,    623200879,    774790258,    471611428,  -1499047951,  -1263242297,   -960063663, 
1035                 -387396829,   -572677764,   1953818780,    522141217,   1263245021,  -1111662116,  -1953821306,  -1970663547, 
1036                 1886445712,   1044282434,  -1246400060,   1718013098,   1212715224,     50529797,   -151587071,    235805714, 
1037                 1633796771,    892693087,   1465364217,  -1179031088,  -2038032495,  -1044276904,    488454695,  -1633802311, 
1038                 -505292488,   -117904621,  -1734857805,    286335539,   1768542907,   -640046736,  -1903294583,  -1802226777, 
1039                -1684329034,    505297954,  -2021190254,   -370554592,   -825325751,   1431677695,    673730680,   -538991238, 
1040                -1936981105,  -1583261192,  -1987507840,    218962455,  -1077975590,   -421079247,   1111655622,   1751699640, 
1041                 1094812355,  -1718015568,    757946999,    252648977,  -1330611253,   1414834428,  -1145344554,    370551866, 
1042
1043                 // s_T3
1044                 1673962851,   2096661628,   2012125559,   2079755643,   -218165774,   1809235307,   1876865391,   -980331323, 
1045                  811618352,     16909057,   1741597031,    727088427,    -18408962,   -675978537,  -1420958037,   1995217526, 
1046                 -896580150,  -2111857278,   -913751863,   2113570685,    -84994566,   1504897881,   1200539975,   -251982864, 
1047                -1388188499,   -726439980,  -1570767454,  -1354372433,  -1675378788,  -1538000988,   1927583346,  -1063560256, 
1048                -1217019209,    -35578627,  -1824674157,    642542118,    913070646,   1065238847,   -134937865,   -863809588, 
1049                  879254580,  -1521355611,   -439274267,   -235337487,   1910674289,   -659852328,    828527409,    355090197, 
1050                   67636228,   -946515257,    591815971,  -1013096765,    405809176,  -1774739050,     84545285,  -1708149350, 
1051                  118360327,    304363026,  -2145674368,   -488686110,   -338876693,    659450151,  -1300247118,   1978310517, 
1052                  152181513,  -2095210877,    743994412,    439627290,    456535323,   1859957358,   1521806938,  -1604584544, 
1053                 1386542674,    997608763,   -692624938,  -1283600717,    693271337,   -472039709,    794718511,  -2079090812, 
1054                 1403450707,   -776378159,            0,   -306107155,    541089824,    -52224004,  -1317418831,   1538714971, 
1055                 1792327274,   -879933749,  -1100490306,    963791673,   1251270218,   1285084236,   1487988824,   -813348145, 
1056                 -793023536,   -272291089,  -1437604438,    -68348165,   1132905795,   1301993293,    862344499,  -2062445435, 
1057                 1166724933,   -102166279,     33818114,   2147385727,   1352724560,   1014514748,  -1624917345,  -1471421528, 
1058                 1369633617,  -1554121053,   1082179648,  -1895462257,  -1841320558,  -1658733411,    946882616,   -168753931, 
1059                -1134305348,  -1233665610,   -626035238,    557998881,    270544912,     -1762561,   -201519373,   -759206446, 
1060                 -847164211,    202904588,    321271059,   -322752532,   1606345055,  -1758092649,   1149815876,    388905239, 
1061                 -996976700,  -1487539545,   2130477694,   1031423805,   1690872932,   1572530013,    422718233,   1944491379, 
1062                 1623236704,  -2129028991,   1335808335,   -593264676,    574907938,    710180394,  -1875137648,  -2012511352, 
1063                 1183631942,   -288937490,  -1200893000,    338181140,   -559449634,   1589437022,    185998603,   -609388837, 
1064                 -522503200,    845436466,    980700730,    169090570,   1234361161,    101452294,    608726052,   1555620956, 
1065                -1029743166,   -742560045,  -1404833876,   1657054818,  -1858492271,  -1791908715,   -455919644,   2045938553, 
1066                 -405458201,   -930397240,    929978679,   1843050349,  -1929278323,   -709794603,   1318900302,  -1454776151, 
1067                 1826141292,   1454176854,   -185399308,   -355523094,   1707781989,   2062847610,  -1371018834,    135272456, 
1068                -1167075910,   2029029496,    625635109,    777810478,    473441308,  -1504185946,  -1267480652,   -963161658, 
1069                 -389340184,   -576619299,   1961401460,    524165407,   1268178251,  -1117659971,  -1962047861,  -1978694262, 
1070                 1893765232,   1048330814,  -1250835275,   1724688998,   1217452104,     50726147,   -151584266,    236720654, 
1071                 1640145761,    896163637,   1471084887,  -1184247623,  -2045275770,  -1046914879,    490350365,  -1641563746, 
1072                 -505857823,   -118811656,  -1741966440,    287453969,   1775418217,   -643206951,  -1912108658,  -1808554092, 
1073                -1691502949,    507257374,  -2028629369,   -372694807,   -829994546,   1437269845,    676362280,   -542803233, 
1074                -1945923700,  -1587939167,  -1995865975,    219813645,  -1083843905,   -422104602,   1115997762,   1758509160, 
1075                 1099088705,  -1725321063,    760903469,    253628687,  -1334064208,   1420360788,  -1150429509,    371997206, 
1076
1077                 // s_T4
1078                -962239645,   -125535108,   -291932297,   -158499973,    -15863054,   -692229269,   -558796945,  -1856715323, 
1079                 1615867952,     33751297,   -827758745,   1451043627,   -417726722,  -1251813417,   1306962859,   -325421450, 
1080                -1891251510,    530416258,  -1992242743,    -91783811,   -283772166,  -1293199015,  -1899411641,    -83103504, 
1081                 1106029997,  -1285040940,   1610457762,   1173008303,    599760028,   1408738468,   -459902350,  -1688485696, 
1082                 1975695287,   -518193667,   1034851219,   1282024998,   1817851446,   2118205247,   -184354825,  -2091922228, 
1083                 1750873140,   1374987685,   -785062427,   -116854287,   -493653647,  -1418471208,   1649619249,    708777237, 
1084                  135005188,  -1789737017,   1181033251,  -1654733885,    807933976,    933336726,    168756485,    800430746, 
1085                  235472647,    607523346,    463175808,   -549592350,   -853087253,   1315514151,   2144187058,   -358648459, 
1086                  303761673,    496927619,   1484008492,    875436570,    908925723,   -592286098,  -1259447718,   1543217312, 
1087                -1527360942,   1984772923,  -1218324778,   2110698419,   1383803177,   -583080989,   1584475951,    328696964, 
1088                -1493871789,  -1184312879,            0,  -1054020115,   1080041504,   -484442884,   2043195825,  -1225958565, 
1089                 -725718422,  -1924740149,   1742323390,   1917532473,  -1797371318,  -1730917300,  -1326950312,  -2058694705, 
1090                -1150562096,   -987041809,   1340451498,   -317260805,  -2033892541,  -1697166003,   1716859699,    294946181, 
1091                -1966127803,   -384763399,     67502594,    -25067649,  -1594863536,   2017737788,    632987551,   1273211048, 
1092                -1561112239,   1576969123,  -2134884288,     92966799,   1068339858,    566009245,   1883781176,   -251333131, 
1093                 1675607228,   2009183926,  -1351230758,   1113792801,    540020752,   -451215361,    -49351693,  -1083321646, 
1094                -2125673011,    403966988,    641012499,  -1020269332,  -1092526241,    899848087,  -1999879100,    775493399, 
1095                -1822964540,   1441965991,    -58556802,   2051489085,   -928226204,  -1159242403,    841685273,   -426413197, 
1096                -1063231392,    429425025,  -1630449841,  -1551901476,   1147544098,   1417554474,   1001099408,    193169544, 
1097                -1932900794,   -953553170,   1809037496,    675025940,  -1485185314,  -1126015394,    371002123,  -1384719397, 
1098                 -616832800,   1683370546,   1951283770,    337512970,  -1831122615,    201983494,   1215046692,  -1192993700, 
1099                -1621245246,  -1116810285,   1139780780,   -995728798,    967348625,    832869781,   -751311644,   -225740423, 
1100                 -718084121,  -1958491960,   1851340599,   -625513107,     25988493,  -1318791723,  -1663938994,   1239460265, 
1101                 -659264404,  -1392880042,   -217582348,   -819598614,   -894474907,   -191989126,   1206496942,    270010376, 
1102                 1876277946,   -259491720,   1248797989,   1550986798,    941890588,   1475454630,   1942467764,  -1756248378, 
1103                 -886839064,  -1585652259,   -392399756,   1042358047,  -1763882165,   1641856445,    226921355,    260409994, 
1104                 -527404944,   2084716094,   1908716981,   -861247898,  -1864873912,    100991747,   -150866186,    470945294, 
1105                -1029480095,   1784624437,  -1359390889,   1775286713,    395413126,  -1722236479,    975641885,    666476190, 
1106                 -650583583,   -351012616,    733190296,    573772049,   -759469719,  -1452221991,    126455438,    866620564, 
1107                  766942107,   1008868894,    361924487,   -920589847,  -2025206066,  -1426107051,   1350051880,  -1518673953, 
1108                   59739276,   1509466529,    159418761,    437718285,   1708834751,   -684595482,  -2067381694,   -793221016, 
1109                -2101132991,    699439513,   1517759789,    504434447,   2076946608,  -1459858348,   1842789307,    742004246 };
1110
1111         private static readonly int[] s_TF = new int[4 * 256]
1112             {
1113                         // s_TF1
1114                         99,          124,          119,          123,          242,          107,          111,          197, 
1115                         48,            1,          103,           43,          254,          215,          171,          118, 
1116                        202,          130,          201,          125,          250,           89,           71,          240, 
1117                        173,          212,          162,          175,          156,          164,          114,          192, 
1118                        183,          253,          147,           38,           54,           63,          247,          204, 
1119                         52,          165,          229,          241,          113,          216,           49,           21, 
1120                          4,          199,           35,          195,           24,          150,            5,          154, 
1121                          7,           18,          128,          226,          235,           39,          178,          117, 
1122                          9,          131,           44,           26,           27,          110,           90,          160, 
1123                         82,           59,          214,          179,           41,          227,           47,          132, 
1124                         83,          209,            0,          237,           32,          252,          177,           91, 
1125                        106,          203,          190,           57,           74,           76,           88,          207, 
1126                        208,          239,          170,          251,           67,           77,           51,          133, 
1127                         69,          249,            2,          127,           80,           60,          159,          168, 
1128                         81,          163,           64,          143,          146,          157,           56,          245, 
1129                        188,          182,          218,           33,           16,          255,          243,          210, 
1130                        205,           12,           19,          236,           95,          151,           68,           23, 
1131                        196,          167,          126,           61,          100,           93,           25,          115, 
1132                         96,          129,           79,          220,           34,           42,          144,          136, 
1133                         70,          238,          184,           20,          222,           94,           11,          219, 
1134                        224,           50,           58,           10,           73,            6,           36,           92, 
1135                        194,          211,          172,           98,          145,          149,          228,          121, 
1136                        231,          200,           55,          109,          141,          213,           78,          169, 
1137                        108,           86,          244,          234,          101,          122,          174,            8, 
1138                        186,          120,           37,           46,           28,          166,          180,          198, 
1139                        232,          221,          116,           31,           75,          189,          139,          138, 
1140                        112,           62,          181,          102,           72,            3,          246,           14, 
1141                         97,           53,           87,          185,          134,          193,           29,          158, 
1142                        225,          248,          152,           17,          105,          217,          142,          148, 
1143                        155,           30,          135,          233,          206,           85,           40,          223, 
1144                        140,          161,          137,           13,          191,          230,           66,          104, 
1145                         65,          153,           45,           15,          176,           84,          187,           22, 
1146
1147                         // s_TF2
1148                      25344,        31744,        30464,        31488,        61952,        27392,        28416,        50432, 
1149                      12288,          256,        26368,        11008,        65024,        55040,        43776,        30208, 
1150                      51712,        33280,        51456,        32000,        64000,        22784,        18176,        61440, 
1151                      44288,        54272,        41472,        44800,        39936,        41984,        29184,        49152, 
1152                      46848,        64768,        37632,         9728,        13824,        16128,        63232,        52224, 
1153                      13312,        42240,        58624,        61696,        28928,        55296,        12544,         5376, 
1154                       1024,        50944,         8960,        49920,         6144,        38400,         1280,        39424, 
1155                       1792,         4608,        32768,        57856,        60160,         9984,        45568,        29952, 
1156                       2304,        33536,        11264,         6656,         6912,        28160,        23040,        40960, 
1157                      20992,        15104,        54784,        45824,        10496,        58112,        12032,        33792, 
1158                      21248,        53504,            0,        60672,         8192,        64512,        45312,        23296, 
1159                      27136,        51968,        48640,        14592,        18944,        19456,        22528,        52992, 
1160                      53248,        61184,        43520,        64256,        17152,        19712,        13056,        34048, 
1161                      17664,        63744,          512,        32512,        20480,        15360,        40704,        43008, 
1162                      20736,        41728,        16384,        36608,        37376,        40192,        14336,        62720, 
1163                      48128,        46592,        55808,         8448,         4096,        65280,        62208,        53760, 
1164                      52480,         3072,         4864,        60416,        24320,        38656,        17408,         5888, 
1165                      50176,        42752,        32256,        15616,        25600,        23808,         6400,        29440, 
1166                      24576,        33024,        20224,        56320,         8704,        10752,        36864,        34816, 
1167                      17920,        60928,        47104,         5120,        56832,        24064,         2816,        56064, 
1168                      57344,        12800,        14848,         2560,        18688,         1536,         9216,        23552, 
1169                      49664,        54016,        44032,        25088,        37120,        38144,        58368,        30976, 
1170                      59136,        51200,        14080,        27904,        36096,        54528,        19968,        43264, 
1171                      27648,        22016,        62464,        59904,        25856,        31232,        44544,         2048, 
1172                      47616,        30720,         9472,        11776,         7168,        42496,        46080,        50688, 
1173                      59392,        56576,        29696,         7936,        19200,        48384,        35584,        35328, 
1174                      28672,        15872,        46336,        26112,        18432,          768,        62976,         3584, 
1175                      24832,        13568,        22272,        47360,        34304,        49408,         7424,        40448, 
1176                      57600,        63488,        38912,         4352,        26880,        55552,        36352,        37888, 
1177                      39680,         7680,        34560,        59648,        52736,        21760,        10240,        57088, 
1178                      35840,        41216,        35072,         3328,        48896,        58880,        16896,        26624, 
1179                      16640,        39168,        11520,         3840,        45056,        21504,        47872,         5632, 
1180
1181                         // s_TF3
1182                    6488064,      8126464,      7798784,      8060928,     15859712,      7012352,      7274496,     12910592, 
1183                    3145728,        65536,      6750208,      2818048,     16646144,     14090240,     11206656,      7733248, 
1184                   13238272,      8519680,     13172736,      8192000,     16384000,      5832704,      4653056,     15728640, 
1185                   11337728,     13893632,     10616832,     11468800,     10223616,     10747904,      7471104,     12582912, 
1186                   11993088,     16580608,      9633792,      2490368,      3538944,      4128768,     16187392,     13369344, 
1187                    3407872,     10813440,     15007744,     15794176,      7405568,     14155776,      3211264,      1376256, 
1188                     262144,     13041664,      2293760,     12779520,      1572864,      9830400,       327680,     10092544, 
1189                     458752,      1179648,      8388608,     14811136,     15400960,      2555904,     11665408,      7667712, 
1190                     589824,      8585216,      2883584,      1703936,      1769472,      7208960,      5898240,     10485760, 
1191                    5373952,      3866624,     14024704,     11730944,      2686976,     14876672,      3080192,      8650752, 
1192                    5439488,     13697024,            0,     15532032,      2097152,     16515072,     11599872,      5963776, 
1193                    6946816,     13303808,     12451840,      3735552,      4849664,      4980736,      5767168,     13565952, 
1194                   13631488,     15663104,     11141120,     16449536,      4390912,      5046272,      3342336,      8716288, 
1195                    4521984,     16318464,       131072,      8323072,      5242880,      3932160,     10420224,     11010048, 
1196                    5308416,     10682368,      4194304,      9371648,      9568256,     10289152,      3670016,     16056320, 
1197                   12320768,     11927552,     14286848,      2162688,      1048576,     16711680,     15925248,     13762560, 
1198                   13434880,       786432,      1245184,     15466496,      6225920,      9895936,      4456448,      1507328, 
1199                   12845056,     10944512,      8257536,      3997696,      6553600,      6094848,      1638400,      7536640, 
1200                    6291456,      8454144,      5177344,     14417920,      2228224,      2752512,      9437184,      8912896, 
1201                    4587520,     15597568,     12058624,      1310720,     14548992,      6160384,       720896,     14352384, 
1202                   14680064,      3276800,      3801088,       655360,      4784128,       393216,      2359296,      6029312, 
1203                   12713984,     13828096,     11272192,      6422528,      9502720,      9764864,     14942208,      7929856, 
1204                   15138816,     13107200,      3604480,      7143424,      9240576,     13959168,      5111808,     11075584, 
1205                    7077888,      5636096,     15990784,     15335424,      6619136,      7995392,     11403264,       524288, 
1206                   12189696,      7864320,      2424832,      3014656,      1835008,     10878976,     11796480,     12976128, 
1207                   15204352,     14483456,      7602176,      2031616,      4915200,     12386304,      9109504,      9043968, 
1208                    7340032,      4063232,     11862016,      6684672,      4718592,       196608,     16121856,       917504, 
1209                    6356992,      3473408,      5701632,     12124160,      8781824,     12648448,      1900544,     10354688, 
1210                   14745600,     16252928,      9961472,      1114112,      6881280,     14221312,      9306112,      9699328, 
1211                   10158080,      1966080,      8847360,     15269888,     13500416,      5570560,      2621440,     14614528, 
1212                    9175040,     10551296,      8978432,       851968,     12517376,     15073280,      4325376,      6815744, 
1213                    4259840,     10027008,      2949120,       983040,     11534336,      5505024,     12255232,      1441792, 
1214
1215                         // s_TF4
1216                 1660944384,   2080374784,   1996488704,   2063597568,   -234881024,   1795162112,   1862270976,   -989855744, 
1217                  805306368,     16777216,   1728053248,    721420288,    -33554432,   -687865856,  -1426063360,   1979711488, 
1218                 -905969664,  -2113929216,   -922746880,   2097152000,   -100663296,   1493172224,   1191182336,   -268435456, 
1219                -1392508928,   -738197504,  -1577058304,  -1358954496,  -1677721600,  -1543503872,   1912602624,  -1073741824, 
1220                -1224736768,    -50331648,  -1828716544,    637534208,    905969664,   1056964608,   -150994944,   -872415232, 
1221                  872415232,  -1526726656,   -452984832,   -251658240,   1895825408,   -671088640,    822083584,    352321536, 
1222                   67108864,   -956301312,    587202560,  -1023410176,    402653184,  -1778384896,     83886080,  -1711276032, 
1223                  117440512,    301989888,  -2147483648,   -503316480,   -352321536,    654311424,  -1308622848,   1962934272, 
1224                  150994944,  -2097152000,    738197504,    436207616,    452984832,   1845493760,   1509949440,  -1610612736, 
1225                 1375731712,    989855744,   -704643072,  -1291845632,    687865856,   -486539264,    788529152,  -2080374784, 
1226                 1392508928,   -788529152,            0,   -318767104,    536870912,    -67108864,  -1325400064,   1526726656, 
1227                 1778384896,   -889192448,  -1107296256,    956301312,   1241513984,   1275068416,   1476395008,   -822083584, 
1228                 -805306368,   -285212672,  -1442840576,    -83886080,   1124073472,   1291845632,    855638016,  -2063597568, 
1229                 1157627904,   -117440512,     33554432,   2130706432,   1342177280,   1006632960,  -1627389952,  -1476395008, 
1230                 1358954496,  -1560281088,   1073741824,  -1895825408,  -1845493760,  -1660944384,    939524096,   -184549376, 
1231                -1140850688,  -1241513984,   -637534208,    553648128,    268435456,    -16777216,   -218103808,   -771751936, 
1232                 -855638016,    201326592,    318767104,   -335544320,   1593835520,  -1761607680,   1140850688,    385875968, 
1233                -1006632960,  -1493172224,   2113929216,   1023410176,   1677721600,   1560281088,    419430400,   1929379840, 
1234                 1610612736,  -2130706432,   1325400064,   -603979776,    570425344,    704643072,  -1879048192,  -2013265920, 
1235                 1174405120,   -301989888,  -1207959552,    335544320,   -570425344,   1577058304,    184549376,   -620756992, 
1236                 -536870912,    838860800,    973078528,    167772160,   1224736768,    100663296,    603979776,   1543503872, 
1237                -1040187392,   -754974720,  -1409286144,   1644167168,  -1862270976,  -1795162112,   -469762048,   2030043136, 
1238                 -419430400,   -939524096,    922746880,   1828716544,  -1929379840,   -721420288,   1308622848,  -1459617792, 
1239                 1811939328,   1442840576,   -201326592,   -369098752,   1694498816,   2046820352,  -1375731712,    134217728, 
1240                -1174405120,   2013265920,    620756992,    771751936,    469762048,  -1509949440,  -1275068416,   -973078528, 
1241                 -402653184,   -587202560,   1946157056,    520093696,   1258291200,  -1124073472,  -1962934272,  -1979711488, 
1242                 1879048192,   1040187392,  -1258291200,   1711276032,   1207959552,     50331648,   -167772160,    234881024, 
1243                 1627389952,    889192448,   1459617792,  -1191182336,  -2046820352,  -1056964608,    486539264,  -1644167168, 
1244                 -520093696,   -134217728,  -1744830464,    285212672,   1761607680,   -654311424,  -1912602624,  -1811939328, 
1245                -1694498816,    503316480,  -2030043136,   -385875968,   -838860800,   1426063360,    671088640,   -553648128, 
1246                -1946157056,  -1593835520,  -1996488704,    218103808,  -1090519040,   -436207616,   1107296256,   1744830464, 
1247                 1090519040,  -1728053248,    754974720,    251658240,  -1342177280,   1409286144,  -1157627904,    369098752 };
1248
1249         private static readonly int[] s_iT = new int[4 * 256]
1250             {
1251                 // s_iT1
1252                 1353184337,   1399144830,  -1012656358,  -1772214470,   -882136261,   -247096033,  -1420232020,  -1828461749, 
1253                 1442459680,   -160598355,  -1854485368,    625738485,    -52959921,   -674551099,  -2143013594,  -1885117771, 
1254                 1230680542,   1729870373,  -1743852987,   -507445667,     41234371,    317738113,  -1550367091,   -956705941, 
1255                 -413167869,  -1784901099,   -344298049,   -631680363,    763608788,   -752782248,    694804553,   1154009486, 
1256                 1787413109,   2021232372,   1799248025,   -579749593,  -1236278850,    397248752,   1722556617,  -1271214467, 
1257                  407560035,  -2110711067,   1613975959,   1165972322,   -529046351,  -2068943941,    480281086,  -1809118983, 
1258                 1483229296,    436028815,  -2022908268,  -1208452270,    601060267,   -503166094,   1468997603,    715871590, 
1259                  120122290,     63092015,  -1703164538,  -1526188077,   -226023376,  -1297760477,  -1167457534,   1552029421, 
1260                  723308426,  -1833666137,   -252573709,  -1578997426,   -839591323,   -708967162,    526529745,  -1963022652, 
1261                -1655493068,  -1604979806,    853641733,   1978398372,    971801355,  -1427152832,    111112542,   1360031421, 
1262                 -108388034,   1023860118,  -1375387939,   1186850381,  -1249028975,     90031217,   1876166148,    -15380384, 
1263                  620468249,  -1746289194,   -868007799,   2006899047,  -1119688528,  -2004121337,    945494503,   -605108103, 
1264                 1191869601,   -384875908,   -920746760,            0,  -2088337399,   1223502642,  -1401941730,   1316117100, 
1265                  -67170563,   1446544655,    517320253,    658058550,   1691946762,    564550760,   -783000677,    976107044, 
1266                -1318647284,    266819475,   -761860428,  -1634624741,   1338359936,  -1574904735,   1766553434,    370807324, 
1267                  179999714,   -450191168,   1138762300,    488053522,    185403662,  -1379431438,  -1180125651,   -928440812, 
1268                -2061897385,   1275557295,  -1143105042,    -44007517,  -1624899081,  -1124765092,   -985962940,    880737115, 
1269                 1982415755,   -590994485,   1761406390,   1676797112,   -891538985,    277177154,   1076008723,    538035844, 
1270                 2099530373,   -130171950,    288553390,   1839278535,   1261411869,   -214912292,   -330136051,   -790380169, 
1271                 1813426987,  -1715900247,    -95906799,    577038663,   -997393240,    440397984,   -668172970,   -275762398, 
1272                 -951170681,  -1043253031,    -22885748,    906744984,   -813566554,    685669029,    646887386,  -1530942145, 
1273                 -459458004,    227702864,  -1681105046,   1648787028,  -1038905866,   -390539120,   1593260334,   -173030526, 
1274                -1098883681,   2090061929,  -1456614033,  -1290656305,    999926984,  -1484974064,   1852021992,   2075868123, 
1275                  158869197,   -199730834,     28809964,  -1466282109,   1701746150,   2129067946,    147831841,   -420997649, 
1276                 -644094022,   -835293366,   -737566742,   -696471511,  -1347247055,    824393514,    815048134,  -1067015627, 
1277                  935087732,  -1496677636,  -1328508704,    366520115,   1251476721,   -136647615,    240176511,    804688151, 
1278                -1915335306,   1303441219,   1414376140,   -553347356,   -474623586,    461924940,  -1205916479,   2136040774, 
1279                   82468509,   1563790337,   1937016826,    776014843,   1511876531,   1389550482,    861278441,    323475053, 
1280                -1939744870,   2047648055,  -1911228327,  -1992551445,   -299390514,    902390199,   -303751967,   1018251130, 
1281                 1507840668,   1064563285,   2043548696,  -1086863501,   -355600557,   1537932639,    342834655,  -2032450440, 
1282                -2114736182,   1053059257,    741614648,   1598071746,   1925389590,    203809468,  -1958134744,   1100287487, 
1283                 1895934009,   -558691320,  -1662733096,  -1866377628,   1636092795,   1890988757,   1952214088,   1113045200, 
1284
1285                 // s_iT2
1286                -1477160624,   1698790995,  -1541989693,   1579629206,   1806384075,   1167925233,   1492823211,     65227667, 
1287                  -97509291,   1836494326,   1993115793,   1275262245,   -672837636,   -886389289,   1144333952,  -1553812081, 
1288                 1521606217,    465184103,    250234264,  -1057071647,   1966064386,   -263421678,  -1756983901,   -103584826, 
1289                 1603208167,  -1668147819,   2054012907,   1498584538,  -2084645843,    561273043,   1776306473,   -926314940, 
1290                -1983744662,   2039411832,   1045993835,   1907959773,   1340194486,  -1383534569,  -1407137434,    986611124, 
1291                 1256153880,    823846274,    860985184,   2136171077,   2003087840,  -1368671356,  -1602093540,    722008468, 
1292                 1749577816,    -45773031,   1826526343,   -126135625,   -747394269,     38499042,  -1893735593,  -1420466646, 
1293                  686535175,  -1028313341,   2076542618,    137876389,  -2027409166,  -1514200142,   1778582202,  -2112426660, 
1294                  483363371,  -1267095662,   -234359824,   -496415071,   -187013683,  -1106966827,   1647628575,    -22625142, 
1295                 1395537053,   1442030240,   -511048398,   -336157579,   -326956231,   -278904662,  -1619960314,    275692881, 
1296                -1977532679,    115185213,     88006062,  -1108980410,  -1923837515,   1573155077,   -737803153,    357589247, 
1297                  -73918172,   -373434729,   1128303052,  -1629919369,   1122545853,  -1953953912,   1528424248,   -288851493, 
1298                  175939911,    256015593,    512030921,            0,  -2038429309,   -315936184,   1880170156,   1918528590, 
1299                  -15794693,    948244310,   -710001378,    959264295,   -653325724,  -1503893471,   1415289809,    775300154, 
1300                 1728711857,   -413691121,  -1762741038,  -1852105826,   -977239985,    551313826,   1266113129,    437394454, 
1301                -1164713462,    715178213,   -534627261,    387650077,    218697227,   -947129683,  -1464455751,  -1457646392, 
1302                  435246981,    125153100,   -577114437,   1618977789,    637663135,   -177054532,    996558021,   2130402100, 
1303                  692292470,   -970732580,    -51530136,   -236668829,   -600713270,  -2057092592,    580326208,    298222624, 
1304                  608863613,   1035719416,    855223825,  -1591097491,    798891339,    817028339,   1384517100,   -473860144, 
1305                  380840812,  -1183798887,   1217663482,   1693009698,  -1929598780,   1072734234,    746411736,  -1875696913, 
1306                 1313441735,   -784803391,  -1563783938,    198481974,  -2114607409,   -562387672,  -1900553690,  -1079165020, 
1307                -1657131804,  -1837608947,   -866162021,   1182684258,    328070850,  -1193766680,   -147247522,  -1346141451, 
1308                -2141347906,  -1815058052,    768962473,    304467891,  -1716729797,   2098729127,   1671227502,  -1153705093, 
1309                 2015808777,    408514292,  -1214583807,  -1706064984,   1855317605,   -419452290,   -809754360,   -401215514, 
1310                -1679312167,    913263310,    161475284,   2091919830,  -1297862225,    591342129,  -1801075152,   1721906624, 
1311                -1135709129,   -897385306,   -795811664,   -660131051,  -1744506550,   -622050825,   1355644686,   -158263505, 
1312                 -699566451,  -1326496947,   1303039060,     76997855,  -1244553501,  -2006299621,    523026872,   1365591679, 
1313                 -362898172,    898367837,   1955068531,   1091304238,    493335386,   -757362094,   1443948851,   1205234963, 
1314                 1641519756,    211892090,    351820174,   1007938441,    665439982,   -916342987,   -451091987,  -1320715716, 
1315                 -539845543,   1945261375,   -837543815,    935818175,   -839429142,  -1426235557,   1866325780,   -616269690, 
1316                 -206583167,   -999769794,    874788908,   1084473951,  -1021503886,    635616268,   1228679307,  -1794244799, 
1317                   27801969,  -1291056930,   -457910116,  -1051302768,  -2067039391,  -1238182544,   1550600308,   1471729730, 
1318
1319                 // s_iT3
1320                 -195997529,   1098797925,    387629988,    658151006,  -1422144661,  -1658851003,    -89347240,   -481586429, 
1321                  807425530,   1991112301,   -863465098,     49620300,   -447742761,    717608907,    891715652,   1656065955, 
1322                -1310832294,  -1171953893,   -364537842,    -27401792,    801309301,   1283527408,   1183687575,   -747911431, 
1323                -1895569569,  -1844079204,   1841294202,   1385552473,  -1093390973,   1951978273,   -532076183,   -913423160, 
1324                -1032492407,  -1896580999,   1486449470,  -1188569743,   -507595185,  -1997531219,    550069932,   -830622662, 
1325                 -547153846,    451248689,   1368875059,   1398949247,   1689378935,   1807451310,  -2114052960,    150574123, 
1326                 1215322216,   1167006205,   -560691348,   2069018616,   1940595667,   1265820162,    534992783,   1432758955, 
1327                 -340654296,  -1255210046,   -981034373,    936617224,    674296455,  -1088179547,     50510442,    384654466, 
1328                 -813028580,   2041025204,    133427442,   1766760930,   -630862348,     84334014,    886120290,  -1497068802, 
1329                  775200083,   -207445931,  -1979370783,   -156994069,  -2096416276,   1614850799,   1901987487,   1857900816, 
1330                  557775242,   -577356538,   1054715397,   -431143235,   1418835341,   -999226019,    100954068,   1348534037, 
1331                -1743182597,  -1110009879,   1082772547,   -647530594,   -391070398,  -1995994997,    434583643,   -931537938, 
1332                 2090944266,   1115482383,  -2064070370,            0,  -2146860154,    724715757,    287222896,   1517047410, 
1333                  251526143,  -2062592456,  -1371726123,    758523705,    252339417,   1550328230,   1536938324,    908343854, 
1334                  168604007,   1469255655,   -290139498,  -1692688751,  -1065332795,   -597581280,   2002413899,    303830554, 
1335                -1813902662,  -1597971158,    574374880,    454171927,    151915277,  -1947030073,  -1238517336,    504678569, 
1336                 -245922535,   1974422535,  -1712407587,   2141453664,     33005350,   1918680309,   1715782971,    -77908866, 
1337                 1133213225,    600562886,   -306812676,   -457677839,    836225756,   1665273989,  -1760346078,   -964419567, 
1338                 1250262308,  -1143801795,   -106032846,    700935585,  -1642247377,  -1294142672,  -2045907886,  -1049112349, 
1339                -1288999914,   1890163129,  -1810761144,   -381214108,    -56048500,   -257942977,   2102843436,    857927568, 
1340                 1233635150,    953795025,   -896729438,   -728222197,   -173617279,   2057644254,  -1210440050,  -1388337985, 
1341                  976020637,   2018512274,   1600822220,   2119459398,  -1913208301,   -661591880,    959340279,  -1014827601, 
1342                 1570750080,   -798393197,   -714102483,    634368786,  -1396163687,    403744637,  -1662488989,   1004239803, 
1343                  650971512,   1500443672,  -1695809097,   1334028442,  -1780062866,     -5603610,  -1138685745,    368043752, 
1344                 -407184997,   1867173430,  -1612000247,  -1339435396,  -1540247630,   1059729699,  -1513738092,  -1573535642, 
1345                 1316239292,  -2097371446,  -1864322864,  -1489824296,     82922136,   -331221030,   -847311280,  -1860751370, 
1346                 1299615190,   -280801872,  -1429449651,  -1763385596,   -778116171,   1783372680,    750893087,   1699118929, 
1347                 1587348714,  -1946067659,  -2013629580,    201010753,   1739807261,   -611167534,    283718486,   -697494713, 
1348                 -677737375,  -1590199796,   -128348652,    334203196,  -1446056409,   1639396809,    484568549,   1199193265, 
1349                 -761505313,   -229294221,    337148366,   -948715721,   -145495347,    -44082262,   1038029935,   1148749531, 
1350                -1345682957,   1756970692,    607661108,  -1547542720,    488010435,   -490992603,   1009290057,    234832277, 
1351                -1472630527,    201907891,  -1260872476,   1449431233,   -881106556,    852848822,   1816687708,  -1194311081, 
1352
1353                 // s_iT4
1354                 1364240372,   2119394625,    449029143,    982933031,   1003187115,    535905693,  -1398056710,   1267925987, 
1355                  542505520,  -1376359050,  -2003732788,   -182105086,   1341970405,   -975713494,    645940277,  -1248877726, 
1356                 -565617999,    627514298,   1167593194,   1575076094,  -1023249105,  -2129465268,  -1918658746,   1808202195, 
1357                   65494927,    362126482,  -1075086739,  -1780852398,   -735214658,   1490231668,   1227450848,  -1908094775, 
1358                 1969916354,   -193431154,  -1721024936,    668823993,  -1095348255,   -266883704,   -916018144,   2108963534, 
1359                 1662536415,   -444452582,  -1755303087,   1648721747,  -1310689436,  -1148932501,    -31678335,   -107730168, 
1360                 1884842056,  -1894122171,  -1803064098,   1387788411,  -1423715469,   1927414347,   -480800993,   1714072405, 
1361                -1308153621,    788775605,  -2036696123,   -744159177,    821200680,    598910399,     45771267,   -312704490, 
1362                -1976886065,  -1483557767,   -202313209,   1319232105,   1707996378,    114671109,   -786472396,   -997523802, 
1363                  882725678,  -1566550541,     87220618,  -1535775754,    188345475,   1084944224,   1577492337,  -1118760850, 
1364                 1056541217,  -1774385443,   -575797954,   1296481766,  -1850372780,   1896177092,     74437638,   1627329872, 
1365                  421854104,   -694687299,  -1983102144,   1735892697,  -1329773848,    126389129,   -415737063,   2044456648, 
1366                -1589179780,   2095648578,   -121037180,            0,    159614592,    843640107,    514617361,   1817080410, 
1367                  -33816818,    257308805,   1025430958,    908540205,    174381327,   1747035740,  -1680780197,    607792694, 
1368                  212952842,  -1827674281,  -1261267218,    463376795,  -2142255680,   1638015196,   1516850039,    471210514, 
1369                 -502613357,  -1058723168,   1011081250,    303896347,    235605257,   -223492213,    767142070,    348694814, 
1370                 1468340721,  -1353971851,   -289677927,  -1543675777,   -140564991,   1555887474,   1153776486,   1530167035, 
1371                -1955190461,   -874723805,  -1234633491,  -1201409564,   -674571215,   1108378979,    322970263,  -2078273082, 
1372                -2055396278,   -755483205,  -1374604551,   -949116631,    491466654,   -588042062,    233591430,   2010178497, 
1373                  728503987,  -1449543312,    301615252,   1193436393,  -1463513860,  -1608892432,   1457007741,    586125363, 
1374                -2016981431,   -641609416,  -1929469238,  -1741288492,  -1496350219,  -1524048262,   -635007305,   1067761581, 
1375                  753179962,   1343066744,   1788595295,   1415726718,   -155053171,  -1863796520,    777975609,  -2097827901, 
1376                -1614905251,   1769771984,   1873358293,   -810347995,   -935618132,    279411992,   -395418724,   -612648133, 
1377                 -855017434,   1861490777,   -335431782,  -2086102449,   -429560171,  -1434523905,    554225596,   -270079979, 
1378                -1160143897,   1255028335,   -355202657,    701922480,    833598116,    707863359,   -969894747,    901801634, 
1379                 1949809742,    -56178046,   -525283184,    857069735,   -246769660,   1106762476,   2131644621,    389019281, 
1380                 1989006925,   1129165039,   -866890326,   -455146346,  -1629243951,   1276872810,  -1044898004,   1182749029, 
1381                -1660622242,     22885772,    -93096825,    -80854773,  -1285939865,  -1840065829,   -382511600,   1829980118, 
1382                -1702075945,    930745505,   1502483704,   -343327725,   -823253079,  -1221211807,   -504503012,   2050797895, 
1383                -1671831598,   1430221810,    410635796,   1941911495,   1407897079,   1599843069,   -552308931,   2022103876, 
1384                 -897453137,  -1187068824,    942421028,  -1033944925,    376619805,  -1140054558,    680216892,    -12479219, 
1385                  963707304,    148812556,   -660806476,   1687208278,   2069988555,   -714033614,   1215585388,   -800958536 };
1386
1387         private static readonly int[] s_iTF = new int[4 * 256]
1388             {
1389                         // s_iTF1
1390                         82,            9,          106,          213,           48,           54,          165,           56, 
1391                        191,           64,          163,          158,          129,          243,          215,          251, 
1392                        124,          227,           57,          130,          155,           47,          255,          135, 
1393                         52,          142,           67,           68,          196,          222,          233,          203, 
1394                         84,          123,          148,           50,          166,          194,           35,           61, 
1395                        238,           76,          149,           11,           66,          250,          195,           78, 
1396                          8,           46,          161,          102,           40,          217,           36,          178, 
1397                        118,           91,          162,           73,          109,          139,          209,           37, 
1398                        114,          248,          246,          100,          134,          104,          152,           22, 
1399                        212,          164,           92,          204,           93,          101,          182,          146, 
1400                        108,          112,           72,           80,          253,          237,          185,          218, 
1401                         94,           21,           70,           87,          167,          141,          157,          132, 
1402                        144,          216,          171,            0,          140,          188,          211,           10, 
1403                        247,          228,           88,            5,          184,          179,           69,            6, 
1404                        208,           44,           30,          143,          202,           63,           15,            2, 
1405                        193,          175,          189,            3,            1,           19,          138,          107, 
1406                         58,          145,           17,           65,           79,          103,          220,          234, 
1407                        151,          242,          207,          206,          240,          180,          230,          115, 
1408                        150,          172,          116,           34,          231,          173,           53,          133, 
1409                        226,          249,           55,          232,           28,          117,          223,          110, 
1410                         71,          241,           26,          113,           29,           41,          197,          137, 
1411                        111,          183,           98,           14,          170,           24,          190,           27, 
1412                        252,           86,           62,           75,          198,          210,          121,           32, 
1413                        154,          219,          192,          254,          120,          205,           90,          244, 
1414                         31,          221,          168,           51,          136,            7,          199,           49, 
1415                        177,           18,           16,           89,           39,          128,          236,           95, 
1416                         96,           81,          127,          169,           25,          181,           74,           13, 
1417                         45,          229,          122,          159,          147,          201,          156,          239, 
1418                        160,          224,           59,           77,          174,           42,          245,          176, 
1419                        200,          235,          187,           60,          131,           83,          153,           97, 
1420                         23,           43,            4,          126,          186,          119,          214,           38, 
1421                        225,          105,           20,           99,           85,           33,           12,          125, 
1422
1423                         // s_iTF2
1424                      20992,         2304,        27136,        54528,        12288,        13824,        42240,        14336, 
1425                      48896,        16384,        41728,        40448,        33024,        62208,        55040,        64256, 
1426                      31744,        58112,        14592,        33280,        39680,        12032,        65280,        34560, 
1427                      13312,        36352,        17152,        17408,        50176,        56832,        59648,        51968, 
1428                      21504,        31488,        37888,        12800,        42496,        49664,         8960,        15616, 
1429                      60928,        19456,        38144,         2816,        16896,        64000,        49920,        19968, 
1430                       2048,        11776,        41216,        26112,        10240,        55552,         9216,        45568, 
1431                      30208,        23296,        41472,        18688,        27904,        35584,        53504,         9472, 
1432                      29184,        63488,        62976,        25600,        34304,        26624,        38912,         5632, 
1433                      54272,        41984,        23552,        52224,        23808,        25856,        46592,        37376, 
1434                      27648,        28672,        18432,        20480,        64768,        60672,        47360,        55808, 
1435                      24064,         5376,        17920,        22272,        42752,        36096,        40192,        33792, 
1436                      36864,        55296,        43776,            0,        35840,        48128,        54016,         2560, 
1437                      63232,        58368,        22528,         1280,        47104,        45824,        17664,         1536, 
1438                      53248,        11264,         7680,        36608,        51712,        16128,         3840,          512, 
1439                      49408,        44800,        48384,          768,          256,         4864,        35328,        27392, 
1440                      14848,        37120,         4352,        16640,        20224,        26368,        56320,        59904, 
1441                      38656,        61952,        52992,        52736,        61440,        46080,        58880,        29440, 
1442                      38400,        44032,        29696,         8704,        59136,        44288,        13568,        34048, 
1443                      57856,        63744,        14080,        59392,         7168,        29952,        57088,        28160, 
1444                      18176,        61696,         6656,        28928,         7424,        10496,        50432,        35072, 
1445                      28416,        46848,        25088,         3584,        43520,         6144,        48640,         6912, 
1446                      64512,        22016,        15872,        19200,        50688,        53760,        30976,         8192, 
1447                      39424,        56064,        49152,        65024,        30720,        52480,        23040,        62464, 
1448                       7936,        56576,        43008,        13056,        34816,         1792,        50944,        12544, 
1449                      45312,         4608,         4096,        22784,         9984,        32768,        60416,        24320, 
1450                      24576,        20736,        32512,        43264,         6400,        46336,        18944,         3328, 
1451                      11520,        58624,        31232,        40704,        37632,        51456,        39936,        61184, 
1452                      40960,        57344,        15104,        19712,        44544,        10752,        62720,        45056, 
1453                      51200,        60160,        47872,        15360,        33536,        21248,        39168,        24832, 
1454                       5888,        11008,         1024,        32256,        47616,        30464,        54784,         9728, 
1455                      57600,        26880,         5120,        25344,        21760,         8448,         3072,        32000, 
1456
1457                         // s_iTF3
1458                    5373952,       589824,      6946816,     13959168,      3145728,      3538944,     10813440,      3670016, 
1459                   12517376,      4194304,     10682368,     10354688,      8454144,     15925248,     14090240,     16449536, 
1460                    8126464,     14876672,      3735552,      8519680,     10158080,      3080192,     16711680,      8847360, 
1461                    3407872,      9306112,      4390912,      4456448,     12845056,     14548992,     15269888,     13303808, 
1462                    5505024,      8060928,      9699328,      3276800,     10878976,     12713984,      2293760,      3997696, 
1463                   15597568,      4980736,      9764864,       720896,      4325376,     16384000,     12779520,      5111808, 
1464                     524288,      3014656,     10551296,      6684672,      2621440,     14221312,      2359296,     11665408, 
1465                    7733248,      5963776,     10616832,      4784128,      7143424,      9109504,     13697024,      2424832, 
1466                    7471104,     16252928,     16121856,      6553600,      8781824,      6815744,      9961472,      1441792, 
1467                   13893632,     10747904,      6029312,     13369344,      6094848,      6619136,     11927552,      9568256, 
1468                    7077888,      7340032,      4718592,      5242880,     16580608,     15532032,     12124160,     14286848, 
1469                    6160384,      1376256,      4587520,      5701632,     10944512,      9240576,     10289152,      8650752, 
1470                    9437184,     14155776,     11206656,            0,      9175040,     12320768,     13828096,       655360, 
1471                   16187392,     14942208,      5767168,       327680,     12058624,     11730944,      4521984,       393216, 
1472                   13631488,      2883584,      1966080,      9371648,     13238272,      4128768,       983040,       131072, 
1473                   12648448,     11468800,     12386304,       196608,        65536,      1245184,      9043968,      7012352, 
1474                    3801088,      9502720,      1114112,      4259840,      5177344,      6750208,     14417920,     15335424, 
1475                    9895936,     15859712,     13565952,     13500416,     15728640,     11796480,     15073280,      7536640, 
1476                    9830400,     11272192,      7602176,      2228224,     15138816,     11337728,      3473408,      8716288, 
1477                   14811136,     16318464,      3604480,     15204352,      1835008,      7667712,     14614528,      7208960, 
1478                    4653056,     15794176,      1703936,      7405568,      1900544,      2686976,     12910592,      8978432, 
1479                    7274496,     11993088,      6422528,       917504,     11141120,      1572864,     12451840,      1769472, 
1480                   16515072,      5636096,      4063232,      4915200,     12976128,     13762560,      7929856,      2097152, 
1481                   10092544,     14352384,     12582912,     16646144,      7864320,     13434880,      5898240,     15990784, 
1482                    2031616,     14483456,     11010048,      3342336,      8912896,       458752,     13041664,      3211264, 
1483                   11599872,      1179648,      1048576,      5832704,      2555904,      8388608,     15466496,      6225920, 
1484                    6291456,      5308416,      8323072,     11075584,      1638400,     11862016,      4849664,       851968, 
1485                    2949120,     15007744,      7995392,     10420224,      9633792,     13172736,     10223616,     15663104, 
1486                   10485760,     14680064,      3866624,      5046272,     11403264,      2752512,     16056320,     11534336, 
1487                   13107200,     15400960,     12255232,      3932160,      8585216,      5439488,     10027008,      6356992, 
1488                    1507328,      2818048,       262144,      8257536,     12189696,      7798784,     14024704,      2490368, 
1489                   14745600,      6881280,      1310720,      6488064,      5570560,      2162688,       786432,      8192000, 
1490
1491                         // s_iTF4
1492                 1375731712,    150994944,   1778384896,   -721420288,    805306368,    905969664,  -1526726656,    939524096, 
1493                -1090519040,   1073741824,  -1560281088,  -1644167168,  -2130706432,   -218103808,   -687865856,    -83886080, 
1494                 2080374784,   -486539264,    956301312,  -2113929216,  -1694498816,    788529152,    -16777216,  -2030043136, 
1495                  872415232,  -1912602624,   1124073472,   1140850688,  -1006632960,   -570425344,   -385875968,   -889192448, 
1496                 1409286144,   2063597568,  -1811939328,    838860800,  -1509949440,  -1040187392,    587202560,   1023410176, 
1497                 -301989888,   1275068416,  -1795162112,    184549376,   1107296256,   -100663296,  -1023410176,   1308622848, 
1498                  134217728,    771751936,  -1593835520,   1711276032,    671088640,   -654311424,    603979776,  -1308622848, 
1499                 1979711488,   1526726656,  -1577058304,   1224736768,   1828716544,  -1962934272,   -788529152,    620756992, 
1500                 1912602624,   -134217728,   -167772160,   1677721600,  -2046820352,   1744830464,  -1744830464,    369098752, 
1501                 -738197504,  -1543503872,   1543503872,   -872415232,   1560281088,   1694498816,  -1241513984,  -1845493760, 
1502                 1811939328,   1879048192,   1207959552,   1342177280,    -50331648,   -318767104,  -1191182336,   -637534208, 
1503                 1577058304,    352321536,   1174405120,   1459617792,  -1493172224,  -1929379840,  -1660944384,  -2080374784, 
1504                -1879048192,   -671088640,  -1426063360,            0,  -1946157056,  -1140850688,   -754974720,    167772160, 
1505                 -150994944,   -469762048,   1476395008,     83886080,  -1207959552,  -1291845632,   1157627904,    100663296, 
1506                 -805306368,    738197504,    503316480,  -1895825408,   -905969664,   1056964608,    251658240,     33554432, 
1507                -1056964608,  -1358954496,  -1124073472,     50331648,     16777216,    318767104,  -1979711488,   1795162112, 
1508                  973078528,  -1862270976,    285212672,   1090519040,   1325400064,   1728053248,   -603979776,   -369098752, 
1509                -1761607680,   -234881024,   -822083584,   -838860800,   -268435456,  -1275068416,   -436207616,   1929379840, 
1510                -1778384896,  -1409286144,   1946157056,    570425344,   -419430400,  -1392508928,    889192448,  -2063597568, 
1511                 -503316480,   -117440512,    922746880,   -402653184,    469762048,   1962934272,   -553648128,   1845493760, 
1512                 1191182336,   -251658240,    436207616,   1895825408,    486539264,    687865856,   -989855744,  -1996488704, 
1513                 1862270976,  -1224736768,   1644167168,    234881024,  -1442840576,    402653184,  -1107296256,    452984832, 
1514                  -67108864,   1442840576,   1040187392,   1258291200,   -973078528,   -771751936,   2030043136,    536870912, 
1515                -1711276032,   -620756992,  -1073741824,    -33554432,   2013265920,   -855638016,   1509949440,   -201326592, 
1516                  520093696,   -587202560,  -1476395008,    855638016,  -2013265920,    117440512,   -956301312,    822083584, 
1517                -1325400064,    301989888,    268435456,   1493172224,    654311424,  -2147483648,   -335544320,   1593835520, 
1518                 1610612736,   1358954496,   2130706432,  -1459617792,    419430400,  -1258291200,   1241513984,    218103808, 
1519                  754974720,   -452984832,   2046820352,  -1627389952,  -1828716544,   -922746880,  -1677721600,   -285212672, 
1520                -1610612736,   -536870912,    989855744,   1291845632,  -1375731712,    704643072,   -184549376,  -1342177280, 
1521                 -939524096,   -352321536,  -1157627904,   1006632960,  -2097152000,   1392508928,  -1728053248,   1627389952, 
1522                  385875968,    721420288,     67108864,   2113929216,  -1174405120,   1996488704,   -704643072,    637534208, 
1523                 -520093696,   1761607680,    335544320,   1660944384,   1426063360,    553648128,    201326592,   2097152000 };
1524     }
1525 }