Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / mscorlib / system / security / cryptography / rijndaelmanagedtransform.cs
blobdc93a6317d82ba40c6761b4a5790b05b6a210222
1 using System.Diagnostics.Contracts;
2 // ==++==
3 //
4 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //
6 // ==--==
7 // <OWNER>Microsoft</OWNER>
8 //
11 // RijndaelManagedTransform.cs
14 namespace System.Security.Cryptography
16 [Serializable]
17 internal enum RijndaelManagedTransformMode {
18 Encrypt = 0,
19 Decrypt = 1
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;
28 private int m_blockSizeBits;
29 private int m_blockSizeBytes;
30 private int m_inputBlockSize;
31 private int m_outputBlockSize;
33 private int[] m_encryptKeyExpansion;
34 private int[] m_decryptKeyExpansion;
36 private int m_Nr;
37 private int m_Nb;
38 private int m_Nk;
40 private int[] m_encryptindex = null;
41 private int[] m_decryptindex = null;
43 private int[] m_IV;
44 private int[] m_lastBlockBuffer;
45 private byte[] m_depadBuffer;
46 private byte[] m_shiftRegister;
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();
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
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;
72 int S1 = m_Nb > 6 ? 3 : 2;
73 int S2 = m_Nb > 6 ? 4 : 3;
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];
80 int[] decryptindex1 = new int[m_Nb];
81 int[] decryptindex2 = new int[m_Nb];
82 int[] decryptindex3 = new int[m_Nb];
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;
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);
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);
103 switch (m_cipherMode) {
104 case CipherMode.ECB:
105 case CipherMode.CBC:
106 m_inputBlockSize = m_blockSizeBytes;
107 m_outputBlockSize = m_blockSizeBytes;
108 break;
110 case CipherMode.CFB:
111 m_inputBlockSize = feedbackSize / 8;
112 m_outputBlockSize = feedbackSize / 8;
113 break;
115 default:
116 throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidCipherMode"));
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"));
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;
137 #if FEATURE_CRYPTO
139 #endif // FEATURE_CRYPTO
141 GenerateKeyExpansion(rgbKey);
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
150 #endif // FEATURE_CRYPTO
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);
157 #endif // FEATURE_CRYPTO
160 #if FEATURE_CORECLR
161 void IDisposable.Dispose()
162 #else
163 public void Dispose()
164 #endif
166 Dispose(true);
169 public void Clear() {
170 Dispose(true);
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;
180 if (m_lastBlockBuffer != null) {
181 Array.Clear(m_lastBlockBuffer, 0, m_lastBlockBuffer.Length);
182 m_lastBlockBuffer = null;
184 if (m_encryptKeyExpansion != null) {
185 Array.Clear(m_encryptKeyExpansion, 0, m_encryptKeyExpansion.Length);
186 m_encryptKeyExpansion = null;
188 if (m_decryptKeyExpansion != null) {
189 Array.Clear(m_decryptKeyExpansion, 0, m_decryptKeyExpansion.Length);
190 m_decryptKeyExpansion = null;
192 if (m_depadBuffer != null) {
193 Array.Clear(m_depadBuffer, 0, m_depadBuffer.Length);
194 m_depadBuffer = null;
196 if (m_shiftRegister != null) {
197 Array.Clear(m_shiftRegister, 0, m_shiftRegister.Length);
198 m_shiftRegister = null;
204 // ICryptoTransform methods and properties.
207 public int BlockSizeValue {
208 get {
209 return m_blockSizeBits;
213 public int InputBlockSize {
214 get {
215 return m_inputBlockSize;
219 public int OutputBlockSize {
220 get {
221 return m_outputBlockSize;
225 public bool CanTransformMultipleBlocks {
226 get {
227 return true;
231 public bool CanReuseTransform {
232 get {
233 return true;
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.
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();
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);
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);
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);
304 #if FEATURE_CRYPTO
306 #endif // FEATURE_CRYPTO
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();
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,
325 m_paddingValue,
326 true);
327 Reset();
328 return transformedBytes;
330 else {
331 if (inputCount%InputBlockSize != 0)
332 throw new CryptographicException(Environment.GetResourceString("Cryptography_SSD_InvalidDataSize"));
334 if (m_depadBuffer == null) {
335 byte[] transformedBytes = null;
336 DecryptData(inputBuffer,
337 inputOffset,
338 inputCount,
339 ref transformedBytes,
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,
352 temp.Length,
353 ref transformedBytes,
355 m_paddingValue,
356 true);
357 Reset();
358 return transformedBytes;
364 // resets the state of the transform
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
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.
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"));
395 int padSize = 0;
396 int lonelyBytes = inputCount % m_inputBlockSize;
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;
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;
425 #endif // FEATURE_CRYPTO
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;
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;
453 #endif // FEATURE_CRYPTO
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"));
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];
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;
495 #if FEATURE_CRYPTO
497 #endif // FEATURE_CRYPTO
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];
506 #if FEATURE_CRYPTO
508 #endif // FEATURE_CRYPTO
510 Enc(encryptindex, encryptKeyExpansion, T, TF, work, temp);
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++]);
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++]);
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++;
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);
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);
565 #if FEATURE_CRYPTO
568 #endif // FEATURE_CRYPTO
569 workBaseIndex += m_inputBlockSize;
576 return (inputCount + padSize);
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.
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"));
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"));
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];
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;
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;
638 #if FEATURE_CRYPTO
640 #endif // FEATURE_CRYPTO
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);
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++]);
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++;
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);
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;
682 #if FEATURE_CRYPTO
684 #endif // FEATURE_CRYPTO
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);
692 #if FEATURE_CRYPTO
694 #endif // FEATURE_CRYPTO
696 workBaseIndex += m_inputBlockSize;
699 if (fLast == false)
700 return inputCount;
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;
749 #endif // FEATURE_CRYPTO
750 outputBuffer = outputBuffer1;
751 return outputBuffer1.Length;
763 // AES encryption function.
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];
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++;
785 for (int i = 0; i < m_Nb; ++i) {
786 work[i] = temp[i];
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++;
803 // AES decryption function.
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++;
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++;
830 for (int i = 0; i < m_Nb; ++i) {
831 work[i] = temp[i];
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++;
850 // Key expansion routine.
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;
859 case 192:
860 m_Nr = 12;
861 break;
863 case 256:
864 m_Nr = 14;
865 break;
867 default:
868 throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
871 m_encryptKeyExpansion = new int[m_Nb * (m_Nr + 1)];
872 m_decryptKeyExpansion = new int[m_Nb * (m_Nr + 1)];
873 int iTemp;
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;
884 if (m_Nk <= 6) {
885 for (int i = m_Nk; i < m_Nb * (m_Nr + 1); ++i) {
886 iTemp = m_encryptKeyExpansion[i-1];
888 if (i % m_Nk == 0) {
889 iTemp = SubWord(rot3(iTemp));
890 iTemp = iTemp ^ s_Rcon[(i / m_Nk) - 1];
893 m_encryptKeyExpansion[i] = m_encryptKeyExpansion[i - m_Nk] ^ iTemp;
895 } else {
896 for (int i = m_Nk; i < m_Nb * (m_Nr + 1); ++i) {
897 iTemp = m_encryptKeyExpansion[i-1];
899 if (i % m_Nk == 0) {
900 iTemp = SubWord(rot3(iTemp));
901 iTemp = iTemp ^ s_Rcon[(i / m_Nk) - 1];
903 else if (i % m_Nk == 4) {
904 iTemp = SubWord(iTemp);
907 m_encryptKeyExpansion[i] = m_encryptKeyExpansion[i - m_Nk] ^ iTemp;
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];
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);
926 private static int rot1(int val) {
927 return (val << 8 & unchecked((int)0xFFFFFF00)) | (val >> 24 & unchecked((int)0x000000FF));
930 private static int rot2(int val) {
931 return (val << 16 & unchecked((int)0xFFFF0000)) | (val >> 16 & unchecked((int)0x0000FFFF));
934 private static int rot3(int val) {
935 return (val << 24 & unchecked((int)0xFF000000)) | (val >> 8 & unchecked((int)0x00FFFFFF));
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;
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);
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 };
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 };
973 private static readonly int[] s_T = new int[4 * 256]
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,
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,
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,
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 };
1111 private static readonly int[] s_TF = new int[4 * 256]
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,
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,
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,
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 };
1249 private static readonly int[] s_iT = new int[4 * 256]
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,
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,
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,
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 };
1387 private static readonly int[] s_iTF = new int[4 * 256]
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,
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,
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,
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 };