2003-02-08 Sebastien Pouliot <spouliot@videotron.ca>
authorSebastien Pouliot <sebastien@ximian.com>
Sat, 8 Feb 2003 12:55:27 +0000 (12:55 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Sat, 8 Feb 2003 12:55:27 +0000 (12:55 -0000)
* Changes to refer Mono.Math and Mono.Security.Cryptography

svn path=/trunk/mcs/; revision=11347

16 files changed:
mcs/class/corlib/System.Security.Cryptography/ChangeLog
mcs/class/corlib/System.Security.Cryptography/DESCryptoServiceProvider.cs
mcs/class/corlib/System.Security.Cryptography/DSACryptoServiceProvider.cs
mcs/class/corlib/System.Security.Cryptography/HMACSHA1.cs
mcs/class/corlib/System.Security.Cryptography/MACTripleDES.cs
mcs/class/corlib/System.Security.Cryptography/PKCS1MaskGenerationMethod.cs
mcs/class/corlib/System.Security.Cryptography/RC2CryptoServiceProvider.cs
mcs/class/corlib/System.Security.Cryptography/RSACryptoServiceProvider.cs
mcs/class/corlib/System.Security.Cryptography/RSAOAEPKeyExchangeDeformatter.cs
mcs/class/corlib/System.Security.Cryptography/RSAOAEPKeyExchangeFormatter.cs
mcs/class/corlib/System.Security.Cryptography/RSAPKCS1KeyExchangeDeformatter.cs
mcs/class/corlib/System.Security.Cryptography/RSAPKCS1KeyExchangeFormatter.cs
mcs/class/corlib/System.Security.Cryptography/RSAPKCS1SignatureDeformatter.cs
mcs/class/corlib/System.Security.Cryptography/RSAPKCS1SignatureFormatter.cs
mcs/class/corlib/System.Security.Cryptography/RijndaelManaged.cs
mcs/class/corlib/System.Security.Cryptography/TripleDESCryptoServiceProvider.cs

index 4d9a665d045a6148da9adbf8ed67c29688723034..db8fea7da3b7153247934401dc731ac7c3431725 100644 (file)
@@ -1,4 +1,8 @@
-2003-03-04  Sebastien Pouliot  <spouliot@videotron.ca>
+2003-02-08  Sebastien Pouliot  <spouliot@videotron.ca>
+
+       * Changes to refer Mono.Math and Mono.Security.Cryptography
+
+2003-02-04  Sebastien Pouliot  <spouliot@videotron.ca>
 
        * CryptoConfig.cs: Added initital support for "machine.config" 
        (limited to algorithms, not OIDs). Modified CreateFromName to use
index f5846fcd1804528f71e26d8a8e5ce8448882566b..3d267af97602975195d4835553cfffe0a3a523e0 100644 (file)
 // System.Security.Cryptography.DESCryptoServiceProvider
 //
 // Authors:
-//   Sergey Chaban (serge@wildwestsoftware.com)
-//   Sebastien Pouliot (spouliot@motus.com)
+//     Sergey Chaban (serge@wildwestsoftware.com)
+//     Sebastien Pouliot (spouliot@motus.com)
 //
 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
 //
 
-
 using System;
+using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography {
 
-// References:
-// a.  FIPS PUB 46-3: Data Encryption Standard
-//     http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
-
-internal class DESTransform : SymmetricTransform {
-
-       internal static readonly int KEY_BIT_SIZE = 64;
-       internal static readonly int KEY_BYTE_SIZE = KEY_BIT_SIZE / 8;
-       internal static readonly int BLOCK_BIT_SIZE = 64;
-       internal static readonly int BLOCK_BYTE_SIZE = BLOCK_BIT_SIZE / 8;
-
-       private byte [] keySchedule;
-       private byte [] byteBuff;
-       private uint [] dwordBuff;
-
-       // S-boxes from FIPS 46-3, Appendix 1, page 17
-       private static byte [] sBoxes = {
-                                       /* S1 */
-               14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
-               0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
-               4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
-               15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
-
-                                       /* S2 */
-               15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
-               3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
-               0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
-               13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
-
-                                       /* S3 */
-               10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
-               13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
-               13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
-               1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
-
-                                       /* S4 */
-               7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
-               13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
-               10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
-               3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
-
-                                       /* S5 */
-               2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
-               14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
-               4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
-               11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
-
-                                       /* S6 */
-               12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
-               10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
-               9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
-               4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
-
-                                       /* S7 */
-               4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
-               13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
-               1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
-               6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
-
-                                       /* S8 */
-               13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
-               1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
-               7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
-               2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
-       };
-
-
-       // P table from page 15, also in Appendix 1, page 18
-       private static byte [] pTab = { 
-               16-1,  7-1, 20-1, 21-1,
-               29-1, 12-1, 28-1, 17-1,
-               1-1, 15-1, 23-1, 26-1,
-               5-1, 18-1, 31-1, 10-1,
-               2-1,  8-1, 24-1, 14-1,
-               32-1, 27-1,  3-1,  9-1,
-               19-1, 13-1, 30-1,  6-1,
-               22-1, 11-1,  4-1, 25-1
-       };
-
-
-       // Permuted choice 1 table, PC-1, page 19
-       // Translated to zero-based format.
-       private static byte [] PC1 = {
-               57-1, 49-1, 41-1, 33-1, 25-1, 17-1,  9-1,
-               1-1, 58-1, 50-1, 42-1, 34-1, 26-1, 18-1,
-               10-1,  2-1, 59-1, 51-1, 43-1, 35-1, 27-1,
-               19-1, 11-1,  3-1, 60-1, 52-1, 44-1, 36-1,
-
-               63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1,
-               7-1, 62-1, 54-1, 46-1, 38-1, 30-1, 22-1,
-               14-1,  6-1, 61-1, 53-1, 45-1, 37-1, 29-1,
-               21-1, 13-1,  5-1, 28-1, 20-1, 12-1,  4-1
-       };
-
-
-       private static byte [] leftRot = {
-               1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
-       };
-
-       private static byte [] leftRotTotal;
-
-       // Permuted choice 2 table, PC-2, page 21
-       // Translated to zero-based format.
-       private static byte [] PC2 = {
-               14-1, 17-1, 11-1, 24-1,  1-1,  5-1,
-               3-1, 28-1, 15-1,  6-1, 21-1, 10-1,
-               23-1, 19-1, 12-1,  4-1, 26-1,  8-1,
-               16-1,  7-1, 27-1, 20-1, 13-1,  2-1,
-               41-1, 52-1, 31-1, 37-1, 47-1, 55-1,
-               30-1, 40-1, 51-1, 45-1, 33-1, 48-1,
-               44-1, 49-1, 39-1, 56-1, 34-1, 53-1,
-               46-1, 42-1, 50-1, 36-1, 29-1, 32-1
-       };
-
-
-       // Initial permutation IP, page 10.
-       // Transposed to 0-based format.
-       private static byte [] ipBits = {
-               58-1, 50-1, 42-1, 34-1, 26-1, 18-1, 10-1,  2-1,
-               60-1, 52-1, 44-1, 36-1, 28-1, 20-1, 12-1,  4-1,
-               62-1, 54-1, 46-1, 38-1, 30-1, 22-1, 14-1,  6-1,
-               64-1, 56-1, 48-1, 40-1, 32-1, 24-1, 16-1,  8-1,
-               57-1, 49-1, 41-1, 33-1, 25-1, 17-1,  9-1,  1-1,
-               59-1, 51-1, 43-1, 35-1, 27-1, 19-1, 11-1,  3-1,
-               61-1, 53-1, 45-1, 37-1, 29-1, 21-1, 13-1,  5-1,
-               63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1,  7-1
-       };
-
-
-       // Final permutation FP = IP^(-1), page 10.
-       // Transposed to 0-based format.
-       private static byte [] fpBits = {
-               40-1,  8-1, 48-1, 16-1, 56-1, 24-1, 64-1, 32-1,
-               39-1,  7-1, 47-1, 15-1, 55-1, 23-1, 63-1, 31-1,
-               38-1,  6-1, 46-1, 14-1, 54-1, 22-1, 62-1, 30-1,
-               37-1,  5-1, 45-1, 13-1, 53-1, 21-1, 61-1, 29-1,
-               36-1,  4-1, 44-1, 12-1, 52-1, 20-1, 60-1, 28-1,
-               35-1,  3-1, 43-1, 11-1, 51-1, 19-1, 59-1, 27-1,
-               34-1,  2-1, 42-1, 10-1, 50-1, 18-1, 58-1, 26-1,
-               33-1,  1-1, 41-1,  9-1, 49-1, 17-1, 57-1, 25-1
-       };
-
-       private static uint [] spBoxes;
-       private static int [] ipTab;
-       private static int [] fpTab;
-
-       static DESTransform ()
-       {
-               spBoxes = new uint [64 * 8];
-
-               int [] pBox = new int [32];
-
-               for (int p = 0; p < 32; p++) {
-                       for (int i = 0; i < 32; i++) {
-                               if (p == pTab [i]) {
-                                       pBox [p] = i;
-                                       break;
+       // References:
+       // a.   FIPS PUB 46-3: Data Encryption Standard
+       //      http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
+       
+       internal class DESTransform : SymmetricTransform {
+       
+               internal static readonly int KEY_BIT_SIZE = 64;
+               internal static readonly int KEY_BYTE_SIZE = KEY_BIT_SIZE / 8;
+               internal static readonly int BLOCK_BIT_SIZE = 64;
+               internal static readonly int BLOCK_BYTE_SIZE = BLOCK_BIT_SIZE / 8;
+       
+               private byte [] keySchedule;
+               private byte [] byteBuff;
+               private uint [] dwordBuff;
+       
+               // S-boxes from FIPS 46-3, Appendix 1, page 17
+               private static byte [] sBoxes = {
+                                               /* S1 */
+                       14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
+                       0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
+                       4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
+                       15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
+       
+                                               /* S2 */
+                       15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
+                       3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
+                       0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
+                       13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
+       
+                                               /* S3 */
+                       10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
+                       13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
+                       13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
+                       1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
+       
+                                               /* S4 */
+                       7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
+                       13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
+                       10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
+                       3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
+       
+                                               /* S5 */
+                       2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
+                       14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
+                       4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
+                       11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
+       
+                                               /* S6 */
+                       12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
+                       10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
+                       9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
+                       4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
+       
+                                               /* S7 */
+                       4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
+                       13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
+                       1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
+                       6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
+       
+                                               /* S8 */
+                       13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
+                       1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
+                       7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
+                       2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
+               };
+       
+       
+               // P table from page 15, also in Appendix 1, page 18
+               private static byte [] pTab = { 
+                       16-1,  7-1, 20-1, 21-1,
+                       29-1, 12-1, 28-1, 17-1,
+                       1-1, 15-1, 23-1, 26-1,
+                       5-1, 18-1, 31-1, 10-1,
+                       2-1,  8-1, 24-1, 14-1,
+                       32-1, 27-1,  3-1,  9-1,
+                       19-1, 13-1, 30-1,  6-1,
+                       22-1, 11-1,  4-1, 25-1
+               };
+       
+       
+               // Permuted choice 1 table, PC-1, page 19
+               // Translated to zero-based format.
+               private static byte [] PC1 = {
+                       57-1, 49-1, 41-1, 33-1, 25-1, 17-1,  9-1,
+                       1-1, 58-1, 50-1, 42-1, 34-1, 26-1, 18-1,
+                       10-1,  2-1, 59-1, 51-1, 43-1, 35-1, 27-1,
+                       19-1, 11-1,  3-1, 60-1, 52-1, 44-1, 36-1,
+       
+                       63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1,
+                       7-1, 62-1, 54-1, 46-1, 38-1, 30-1, 22-1,
+                       14-1,  6-1, 61-1, 53-1, 45-1, 37-1, 29-1,
+                       21-1, 13-1,  5-1, 28-1, 20-1, 12-1,  4-1
+               };
+       
+       
+               private static byte [] leftRot = {
+                       1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+               };
+       
+               private static byte [] leftRotTotal;
+       
+               // Permuted choice 2 table, PC-2, page 21
+               // Translated to zero-based format.
+               private static byte [] PC2 = {
+                       14-1, 17-1, 11-1, 24-1,  1-1,  5-1,
+                       3-1, 28-1, 15-1,  6-1, 21-1, 10-1,
+                       23-1, 19-1, 12-1,  4-1, 26-1,  8-1,
+                       16-1,  7-1, 27-1, 20-1, 13-1,  2-1,
+                       41-1, 52-1, 31-1, 37-1, 47-1, 55-1,
+                       30-1, 40-1, 51-1, 45-1, 33-1, 48-1,
+                       44-1, 49-1, 39-1, 56-1, 34-1, 53-1,
+                       46-1, 42-1, 50-1, 36-1, 29-1, 32-1
+               };
+       
+       
+               // Initial permutation IP, page 10.
+               // Transposed to 0-based format.
+               private static byte [] ipBits = {
+                       58-1, 50-1, 42-1, 34-1, 26-1, 18-1, 10-1,  2-1,
+                       60-1, 52-1, 44-1, 36-1, 28-1, 20-1, 12-1,  4-1,
+                       62-1, 54-1, 46-1, 38-1, 30-1, 22-1, 14-1,  6-1,
+                       64-1, 56-1, 48-1, 40-1, 32-1, 24-1, 16-1,  8-1,
+                       57-1, 49-1, 41-1, 33-1, 25-1, 17-1,  9-1,  1-1,
+                       59-1, 51-1, 43-1, 35-1, 27-1, 19-1, 11-1,  3-1,
+                       61-1, 53-1, 45-1, 37-1, 29-1, 21-1, 13-1,  5-1,
+                       63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1,  7-1
+               };
+       
+       
+               // Final permutation FP = IP^(-1), page 10.
+               // Transposed to 0-based format.
+               private static byte [] fpBits = {
+                       40-1,  8-1, 48-1, 16-1, 56-1, 24-1, 64-1, 32-1,
+                       39-1,  7-1, 47-1, 15-1, 55-1, 23-1, 63-1, 31-1,
+                       38-1,  6-1, 46-1, 14-1, 54-1, 22-1, 62-1, 30-1,
+                       37-1,  5-1, 45-1, 13-1, 53-1, 21-1, 61-1, 29-1,
+                       36-1,  4-1, 44-1, 12-1, 52-1, 20-1, 60-1, 28-1,
+                       35-1,  3-1, 43-1, 11-1, 51-1, 19-1, 59-1, 27-1,
+                       34-1,  2-1, 42-1, 10-1, 50-1, 18-1, 58-1, 26-1,
+                       33-1,  1-1, 41-1,  9-1, 49-1, 17-1, 57-1, 25-1
+               };
+       
+               private static uint [] spBoxes;
+               private static int [] ipTab;
+               private static int [] fpTab;
+       
+               static DESTransform ()
+               {
+                       spBoxes = new uint [64 * 8];
+       
+                       int [] pBox = new int [32];
+       
+                       for (int p = 0; p < 32; p++) {
+                               for (int i = 0; i < 32; i++) {
+                                       if (p == pTab [i]) {
+                                               pBox [p] = i;
+                                               break;
+                                       }
                                }
                        }
-               }
-
-               for (int s = 0; s < 8; s++) { // for each S-box
-                       int sOff = s << 6;
-
-                       for (int i = 0; i < 64; i++) { // inputs
-                               uint sp=0;
-
-                               int indx = (i & 0x20) | ((i & 1) << 4) | ((i >> 1) & 0xF);
-
-                               for (int j = 0; j < 4; j++) { // for each bit in the output
-                                       if ((sBoxes [sOff + indx] & (8 >> j)) != 0) {
-                                               sp |= (uint) (1 << (31 - pBox [(s << 2) + j]));
+       
+                       for (int s = 0; s < 8; s++) { // for each S-box
+                               int sOff = s << 6;
+       
+                               for (int i = 0; i < 64; i++) { // inputs
+                                       uint sp=0;
+       
+                                       int indx = (i & 0x20) | ((i & 1) << 4) | ((i >> 1) & 0xF);
+       
+                                       for (int j = 0; j < 4; j++) { // for each bit in the output
+                                               if ((sBoxes [sOff + indx] & (8 >> j)) != 0) {
+                                                       sp |= (uint) (1 << (31 - pBox [(s << 2) + j]));
+                                               }
                                        }
+       
+                                       spBoxes [sOff + i] = sp;
                                }
-
-                               spBoxes [sOff + i] = sp;
                        }
+       
+                       leftRotTotal = new byte [leftRot.Length];
+       
+                       for (int i = 0; i < leftRot.Length; i++) {
+                               int r = 0;
+                               for (int j = 0; j <= i; r += leftRot [j++]);
+                               leftRotTotal [i]  = (byte) r;
+                       }
+       
+                       InitPermutationTable (ipBits, out ipTab);
+                       InitPermutationTable (fpBits, out fpTab);
+               } // class constructor
+       
+               // Default constructor.
+               internal DESTransform (SymmetricAlgorithm symmAlgo, bool encryption, byte[] key, byte[] iv) : base (symmAlgo, encryption, iv)
+               {
+                       keySchedule = new byte [KEY_BYTE_SIZE * 16];
+                       byteBuff = new byte [BLOCK_BYTE_SIZE];
+                       dwordBuff = new uint [BLOCK_BYTE_SIZE / 4];
+                       SetKey (key);
                }
-
-               leftRotTotal = new byte [leftRot.Length];
-
-               for (int i = 0; i < leftRot.Length; i++) {
-                       int r = 0;
-                       for (int j = 0; j <= i; r += leftRot [j++]);
-                       leftRotTotal [i]  = (byte) r;
-               }
-
-               InitPermutationTable (ipBits, out ipTab);
-               InitPermutationTable (fpBits, out fpTab);
-       } // class constructor
-
-       // Default constructor.
-       internal DESTransform (SymmetricAlgorithm symmAlgo, bool encryption, byte[] key, byte[] iv) : base (symmAlgo, encryption, iv)
-       {
-               keySchedule = new byte [KEY_BYTE_SIZE * 16];
-               byteBuff = new byte [BLOCK_BYTE_SIZE];
-               dwordBuff = new uint [BLOCK_BYTE_SIZE / 4];
-               SetKey (key);
-       }
-
-       private static void InitPermutationTable (byte [] pBits, out int [] permTab)
-       {
-               permTab = new int [8*2 * 8*2 * (64/32)];
-
-               for (int i = 0; i < 16; i++) {
-                       for (int j = 0; j < 16; j++) {
-                               int offs = (i << 5) + (j << 1);
-                               for (int n = 0; n < 64; n++) {
-                                       int bitNum = (int) pBits [n];
-                                       if ((bitNum >> 2 == i) &&
-                                               0 != (j & (8 >> (bitNum & 3)))) {
-                                               permTab [offs + (n >> (3+2))] |= (int) ((0x80808080 & (0xFF << (n & (3 << 3)))) >> (n & 7));
+       
+               private static void InitPermutationTable (byte [] pBits, out int [] permTab)
+               {
+                       permTab = new int [8*2 * 8*2 * (64/32)];
+       
+                       for (int i = 0; i < 16; i++) {
+                               for (int j = 0; j < 16; j++) {
+                                       int offs = (i << 5) + (j << 1);
+                                       for (int n = 0; n < 64; n++) {
+                                               int bitNum = (int) pBits [n];
+                                               if ((bitNum >> 2 == i) &&
+                                                       0 != (j & (8 >> (bitNum & 3)))) {
+                                                       permTab [offs + (n >> (3+2))] |= (int) ((0x80808080 & (0xFF << (n & (3 << 3)))) >> (n & 7));
+                                               }
                                        }
                                }
                        }
                }
-       }
-
-       private uint CipherFunct(uint r, int n)
-       {
-               uint res = 0;
-               byte [] subkey = keySchedule;
-               int i = n << 3;
-
-               uint rt = (r >> 1) | (r << 31); // ROR32(r)
-               res |= spBoxes [0*64 + (((rt >> 26) ^ subkey [i++]) & 0x3F)];
-               res |= spBoxes [1*64 + (((rt >> 22) ^ subkey [i++]) & 0x3F)];
-               res |= spBoxes [2*64 + (((rt >> 18) ^ subkey [i++]) & 0x3F)];
-               res |= spBoxes [3*64 + (((rt >> 14) ^ subkey [i++]) & 0x3F)];
-               res |= spBoxes [4*64 + (((rt >> 10) ^ subkey [i++]) & 0x3F)];
-               res |= spBoxes [5*64 + (((rt >>  6) ^ subkey [i++]) & 0x3F)];
-               res |= spBoxes [6*64 + (((rt >>  2) ^ subkey [i++]) & 0x3F)];
-               rt = (r << 1) | (r >> 31); // ROL32(r)
-               res |= spBoxes [7*64 + ((rt ^ subkey [i]) & 0x3F)];
-
-               return res;
-       }
-
-
-       private static void Permutation (byte [] input, byte [] _output, int [] permTab, bool preSwap)
-       {
-               if (preSwap) BSwap (input);
-
-               byte [] output = _output;
-
-               int offs1 = (((int)(input [0]) >> 4)) << 1;
-               int offs2 = (1 << 5) + ((((int)input [0]) & 0xF) << 1);
-
-               int d1 = permTab [offs1++] | permTab [offs2++];
-               int d2 = permTab [offs1]   | permTab [offs2];
-
-
-               int max = BLOCK_BYTE_SIZE << 1;
-               for (int i = 2, indx = 1; i < max; i += 2, indx++) {
-                       int ii = (int) input [indx];
-                       offs1 = (i << 5) + ((ii >> 4) << 1);
-                       offs2 = ((i + 1) << 5) + ((ii & 0xF) << 1);
-
-                       d1 |= permTab [offs1++] | permTab [offs2++];
-                       d2 |= permTab [offs1]   | permTab [offs2];
+       
+               private uint CipherFunct(uint r, int n)
+               {
+                       uint res = 0;
+                       byte [] subkey = keySchedule;
+                       int i = n << 3;
+       
+                       uint rt = (r >> 1) | (r << 31); // ROR32(r)
+                       res |= spBoxes [0*64 + (((rt >> 26) ^ subkey [i++]) & 0x3F)];
+                       res |= spBoxes [1*64 + (((rt >> 22) ^ subkey [i++]) & 0x3F)];
+                       res |= spBoxes [2*64 + (((rt >> 18) ^ subkey [i++]) & 0x3F)];
+                       res |= spBoxes [3*64 + (((rt >> 14) ^ subkey [i++]) & 0x3F)];
+                       res |= spBoxes [4*64 + (((rt >> 10) ^ subkey [i++]) & 0x3F)];
+                       res |= spBoxes [5*64 + (((rt >>  6) ^ subkey [i++]) & 0x3F)];
+                       res |= spBoxes [6*64 + (((rt >>  2) ^ subkey [i++]) & 0x3F)];
+                       rt = (r << 1) | (r >> 31); // ROL32(r)
+                       res |= spBoxes [7*64 + ((rt ^ subkey [i]) & 0x3F)];
+       
+                       return res;
                }
-
-               if (preSwap) {
-                       output [0] = (byte) (d1);
-                       output [1] = (byte) (d1 >> 8);
-                       output [2] = (byte) (d1 >> 16);
-                       output [3] = (byte) (d1 >> 24);
-                       output [4] = (byte) (d2);
-                       output [5] = (byte) (d2 >> 8);
-                       output [6] = (byte) (d2 >> 16);
-                       output [7] = (byte) (d2 >> 24);
-               } else {
-                       output [0] = (byte) (d1 >> 24);
-                       output [1] = (byte) (d1 >> 16);
-                       output [2] = (byte) (d1 >> 8);
-                       output [3] = (byte) (d1);
-                       output [4] = (byte) (d2 >> 24);
-                       output [5] = (byte) (d2 >> 16);
-                       output [6] = (byte) (d2 >> 8);
-                       output [7] = (byte) (d2);
+       
+       
+               private static void Permutation (byte [] input, byte [] _output, int [] permTab, bool preSwap)
+               {
+                       if (preSwap) BSwap (input);
+       
+                       byte [] output = _output;
+       
+                       int offs1 = (((int)(input [0]) >> 4)) << 1;
+                       int offs2 = (1 << 5) + ((((int)input [0]) & 0xF) << 1);
+       
+                       int d1 = permTab [offs1++] | permTab [offs2++];
+                       int d2 = permTab [offs1]   | permTab [offs2];
+       
+       
+                       int max = BLOCK_BYTE_SIZE << 1;
+                       for (int i = 2, indx = 1; i < max; i += 2, indx++) {
+                               int ii = (int) input [indx];
+                               offs1 = (i << 5) + ((ii >> 4) << 1);
+                               offs2 = ((i + 1) << 5) + ((ii & 0xF) << 1);
+       
+                               d1 |= permTab [offs1++] | permTab [offs2++];
+                               d2 |= permTab [offs1]   | permTab [offs2];
+                       }
+       
+                       if (preSwap) {
+                               output [0] = (byte) (d1);
+                               output [1] = (byte) (d1 >> 8);
+                               output [2] = (byte) (d1 >> 16);
+                               output [3] = (byte) (d1 >> 24);
+                               output [4] = (byte) (d2);
+                               output [5] = (byte) (d2 >> 8);
+                               output [6] = (byte) (d2 >> 16);
+                               output [7] = (byte) (d2 >> 24);
+                       } else {
+                               output [0] = (byte) (d1 >> 24);
+                               output [1] = (byte) (d1 >> 16);
+                               output [2] = (byte) (d1 >> 8);
+                               output [3] = (byte) (d1);
+                               output [4] = (byte) (d2 >> 24);
+                               output [5] = (byte) (d2 >> 16);
+                               output [6] = (byte) (d2 >> 8);
+                               output [7] = (byte) (d2);
+                       }
                }
-       }
-
-       private static void BSwap (byte [] byteBuff)
-       {
-               byte t;
-
-               t = byteBuff [0];
-               byteBuff [0] = byteBuff [3];
-               byteBuff [3] = t;
-
-               t = byteBuff [1];
-               byteBuff [1] = byteBuff [2];
-               byteBuff [2] = t;
-
-               t = byteBuff [4];
-               byteBuff [4] = byteBuff [7];
-               byteBuff [7] = t;
-
-               t = byteBuff [5];
-               byteBuff [5] = byteBuff [6];
-               byteBuff [6] = t;
-       }
-
-       internal void SetKey (byte[] key)
-       {
-               // NOTE: see Fig. 3, Key schedule calculation, at page 20.
-               Array.Clear (keySchedule, 0, keySchedule.Length);
-
-               int keyBitSize = PC1.Length;
-
-               byte [] keyPC1 = new byte [keyBitSize]; // PC1-permuted key
-               byte [] keyRot = new byte [keyBitSize]; // PC1 & rotated
-
-               int indx = 0;
-
-               foreach (byte bitPos in PC1) {
-                       keyPC1 [indx++] = (byte)((key [(int)bitPos >> 3] >> (7 ^ (bitPos & 7))) & 1);
+       
+               private static void BSwap (byte [] byteBuff)
+               {
+                       byte t;
+       
+                       t = byteBuff [0];
+                       byteBuff [0] = byteBuff [3];
+                       byteBuff [3] = t;
+       
+                       t = byteBuff [1];
+                       byteBuff [1] = byteBuff [2];
+                       byteBuff [2] = t;
+       
+                       t = byteBuff [4];
+                       byteBuff [4] = byteBuff [7];
+                       byteBuff [7] = t;
+       
+                       t = byteBuff [5];
+                       byteBuff [5] = byteBuff [6];
+                       byteBuff [6] = t;
                }
-
-               int j;
-               for (int i = 0; i < KEY_BYTE_SIZE*2; i++) {
-                       int b = keyBitSize >> 1;
-
-                       for (j = 0; j < b; j++) {
-                               int s = j + (int) leftRotTotal [i];
-                               keyRot [j] = keyPC1 [s < b ? s : s - b];
-                       }
-
-                       for (j = b; j < keyBitSize; j++) {
-                               int s = j + (int) leftRotTotal [i];
-                               keyRot [j] = keyPC1 [s < keyBitSize ? s : s - b];
+       
+               internal void SetKey (byte[] key)
+               {
+                       // NOTE: see Fig. 3, Key schedule calculation, at page 20.
+                       Array.Clear (keySchedule, 0, keySchedule.Length);
+       
+                       int keyBitSize = PC1.Length;
+       
+                       byte [] keyPC1 = new byte [keyBitSize]; // PC1-permuted key
+                       byte [] keyRot = new byte [keyBitSize]; // PC1 & rotated
+       
+                       int indx = 0;
+       
+                       foreach (byte bitPos in PC1) {
+                               keyPC1 [indx++] = (byte)((key [(int)bitPos >> 3] >> (7 ^ (bitPos & 7))) & 1);
                        }
-
-                       int keyOffs = i * KEY_BYTE_SIZE;
-
-                       j = 0;
-                       foreach (byte bitPos in PC2) {
-                               if (keyRot [(int)bitPos] != 0) {
-                                       keySchedule [keyOffs + (j/6)] |= (byte) (0x80 >> ((j % 6) + 2));
+       
+                       int j;
+                       for (int i = 0; i < KEY_BYTE_SIZE*2; i++) {
+                               int b = keyBitSize >> 1;
+       
+                               for (j = 0; j < b; j++) {
+                                       int s = j + (int) leftRotTotal [i];
+                                       keyRot [j] = keyPC1 [s < b ? s : s - b];
+                               }
+       
+                               for (j = b; j < keyBitSize; j++) {
+                                       int s = j + (int) leftRotTotal [i];
+                                       keyRot [j] = keyPC1 [s < keyBitSize ? s : s - b];
+                               }
+       
+                               int keyOffs = i * KEY_BYTE_SIZE;
+       
+                               j = 0;
+                               foreach (byte bitPos in PC2) {
+                                       if (keyRot [(int)bitPos] != 0) {
+                                               keySchedule [keyOffs + (j/6)] |= (byte) (0x80 >> ((j % 6) + 2));
+                                       }
+                                       j++;
                                }
-                               j++;
                        }
                }
-       }
-
-       // public helper for TripleDES
-       public void ProcessBlock (byte[] input, byte[] output) 
-       {
-               ECB (input, output);
-       }
-
-       protected override void ECB (byte[] input, byte[] output) 
-       {
-               byte [] byteBuff = this.byteBuff;
-               uint [] dwordBuff = this.dwordBuff;
-
-               Permutation (input, byteBuff, ipTab, false);
-               Buffer.BlockCopy (byteBuff, 0, dwordBuff, 0, BLOCK_BYTE_SIZE);
-
-               if (encrypt) {
-                       uint d0 = dwordBuff[0];
-                       uint d1 = dwordBuff[1];
-
-                       // 16 rounds
-                       d0 ^= CipherFunct (d1,  0);
-                       d1 ^= CipherFunct (d0,  1);
-                       d0 ^= CipherFunct (d1,  2);
-                       d1 ^= CipherFunct (d0,  3);
-                       d0 ^= CipherFunct (d1,  4);
-                       d1 ^= CipherFunct (d0,  5);
-                       d0 ^= CipherFunct (d1,  6);
-                       d1 ^= CipherFunct (d0,  7);
-                       d0 ^= CipherFunct (d1,  8);
-                       d1 ^= CipherFunct (d0,  9);
-                       d0 ^= CipherFunct (d1, 10);
-                       d1 ^= CipherFunct (d0, 11);
-                       d0 ^= CipherFunct (d1, 12);
-                       d1 ^= CipherFunct (d0, 13);
-                       d0 ^= CipherFunct (d1, 14);
-                       d1 ^= CipherFunct (d0, 15);
-
-                       dwordBuff [0] = d1;
-                       dwordBuff [1] = d0;
+       
+               // public helper for TripleDES
+               public void ProcessBlock (byte[] input, byte[] output) 
+               {
+                       ECB (input, output);
                }
-               else {
-                       uint d1 = dwordBuff [0];
-                       uint d0 = dwordBuff [1];
-
-                       // 16 rounds in reverse order
-                       d1 ^= CipherFunct (d0, 15);
-                       d0 ^= CipherFunct (d1, 14);
-                       d1 ^= CipherFunct (d0, 13);
-                       d0 ^= CipherFunct (d1, 12);
-                       d1 ^= CipherFunct (d0, 11);
-                       d0 ^= CipherFunct (d1, 10);
-                       d1 ^= CipherFunct (d0,  9);
-                       d0 ^= CipherFunct (d1,  8);
-                       d1 ^= CipherFunct (d0,  7);
-                       d0 ^= CipherFunct (d1,  6);
-                       d1 ^= CipherFunct (d0,  5);
-                       d0 ^= CipherFunct (d1,  4);
-                       d1 ^= CipherFunct (d0,  3);
-                       d0 ^= CipherFunct (d1,  2);
-                       d1 ^= CipherFunct (d0,  1);
-                       d0 ^= CipherFunct (d1,  0);
-
-                       dwordBuff [0] = d0;
-                       dwordBuff [1] = d1;
+       
+               protected override void ECB (byte[] input, byte[] output) 
+               {
+                       byte [] byteBuff = this.byteBuff;
+                       uint [] dwordBuff = this.dwordBuff;
+       
+                       Permutation (input, byteBuff, ipTab, false);
+                       Buffer.BlockCopy (byteBuff, 0, dwordBuff, 0, BLOCK_BYTE_SIZE);
+       
+                       if (encrypt) {
+                               uint d0 = dwordBuff[0];
+                               uint d1 = dwordBuff[1];
+       
+                               // 16 rounds
+                               d0 ^= CipherFunct (d1,  0);
+                               d1 ^= CipherFunct (d0,  1);
+                               d0 ^= CipherFunct (d1,  2);
+                               d1 ^= CipherFunct (d0,  3);
+                               d0 ^= CipherFunct (d1,  4);
+                               d1 ^= CipherFunct (d0,  5);
+                               d0 ^= CipherFunct (d1,  6);
+                               d1 ^= CipherFunct (d0,  7);
+                               d0 ^= CipherFunct (d1,  8);
+                               d1 ^= CipherFunct (d0,  9);
+                               d0 ^= CipherFunct (d1, 10);
+                               d1 ^= CipherFunct (d0, 11);
+                               d0 ^= CipherFunct (d1, 12);
+                               d1 ^= CipherFunct (d0, 13);
+                               d0 ^= CipherFunct (d1, 14);
+                               d1 ^= CipherFunct (d0, 15);
+       
+                               dwordBuff [0] = d1;
+                               dwordBuff [1] = d0;
+                       }
+                       else {
+                               uint d1 = dwordBuff [0];
+                               uint d0 = dwordBuff [1];
+       
+                               // 16 rounds in reverse order
+                               d1 ^= CipherFunct (d0, 15);
+                               d0 ^= CipherFunct (d1, 14);
+                               d1 ^= CipherFunct (d0, 13);
+                               d0 ^= CipherFunct (d1, 12);
+                               d1 ^= CipherFunct (d0, 11);
+                               d0 ^= CipherFunct (d1, 10);
+                               d1 ^= CipherFunct (d0,  9);
+                               d0 ^= CipherFunct (d1,  8);
+                               d1 ^= CipherFunct (d0,  7);
+                               d0 ^= CipherFunct (d1,  6);
+                               d1 ^= CipherFunct (d0,  5);
+                               d0 ^= CipherFunct (d1,  4);
+                               d1 ^= CipherFunct (d0,  3);
+                               d0 ^= CipherFunct (d1,  2);
+                               d1 ^= CipherFunct (d0,  1);
+                               d0 ^= CipherFunct (d1,  0);
+       
+                               dwordBuff [0] = d0;
+                               dwordBuff [1] = d1;
+                       }
+       
+                       Buffer.BlockCopy (dwordBuff, 0, byteBuff, 0, BLOCK_BYTE_SIZE);
+                       Permutation (byteBuff, output, fpTab, true);
                }
-
-               Buffer.BlockCopy (dwordBuff, 0, byteBuff, 0, BLOCK_BYTE_SIZE);
-               Permutation (byteBuff, output, fpTab, true);
-       }
-} 
-
-public sealed class DESCryptoServiceProvider : DES {
-
-       public DESCryptoServiceProvider () : base () {}
-
-       public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) 
-       {
-               Key = rgbKey;
-               IV = rgbIV;
-               return new DESTransform (this, false, rgbKey, rgbIV);
-       }
-
-       public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) 
-       {
-               Key = rgbKey;
-               IV = rgbIV;
-               return new DESTransform (this, true, rgbKey, rgbIV);
-       }
-
-       public override void GenerateIV () 
-       {
-               IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
-       }
-
-       public override void GenerateKey () 
-       {
-               KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
-               while (IsWeakKey (KeyValue) || IsSemiWeakKey (KeyValue))
+       } 
+       
+       public sealed class DESCryptoServiceProvider : DES {
+       
+               public DESCryptoServiceProvider () : base () {}
+       
+               public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) 
+               {
+                       Key = rgbKey;
+                       IV = rgbIV;
+                       return new DESTransform (this, false, rgbKey, rgbIV);
+               }
+       
+               public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) 
+               {
+                       Key = rgbKey;
+                       IV = rgbIV;
+                       return new DESTransform (this, true, rgbKey, rgbIV);
+               }
+       
+               public override void GenerateIV () 
+               {
+                       IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
+               }
+       
+               public override void GenerateKey () 
+               {
                        KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
-       }
-
-} // DESCryptoServiceProvider
+                       while (IsWeakKey (KeyValue) || IsSemiWeakKey (KeyValue))
+                               KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
+               }
+       
+       } // DESCryptoServiceProvider
 
 } // System.Security.Cryptography
index 845edeffd9d9855f3687a42a0bffc458632fe58e..b84b084c4af34cf274bb503d4cdc5bb4eefda4e2 100644 (file)
 using System;
 using System.IO;
 
-namespace System.Security.Cryptography {
-
-public class DSACryptoServiceProvider : DSA {
-
-       private CspParameters cspParams;
-       private RandomNumberGenerator rng;
-
-       private bool privateKeyExportable = true;
-       private bool m_disposed = false;
-       private bool keypairGenerated = false;
-       private bool persistKey = false;
-
-       private BigInteger p;
-       private BigInteger q;
-       private BigInteger g;
-       private BigInteger x;   // private key
-       private BigInteger y;
-       private BigInteger j;
-       private BigInteger seed;
-       private int counter;
-
-       public DSACryptoServiceProvider () 
-       {
-               // Here it's not clear if we need to generate a keypair
-               // (note: MS implementation generates a keypair in this case).
-               // However we:
-               // (a) often use this constructor to import an existing keypair.
-               // (b) take a LOT of time to generate the DSA group
-               // So we'll generate the keypair only when (and if) it's being
-               // used (or exported). This should save us a lot of time (at 
-               // least in the unit tests).
-               Common (null);
-       }
-
-       public DSACryptoServiceProvider (CspParameters parameters) 
-       {
-               Common (parameters);
-               // no keypair generation done at this stage
-       }
-
-       // This constructor will generate a new keypair
-       public DSACryptoServiceProvider (int dwKeySize) 
-       {
-               // Here it's clear that we need to generate a new keypair
-               Common (null);
-               Generate (dwKeySize);
-       }
-
-       // This constructor will generate a new keypair
-       public DSACryptoServiceProvider (int dwKeySize, CspParameters parameters) 
-       {
-               Common (parameters);
-               Generate (dwKeySize);
-       }
+using Mono.Math;
 
-       ~DSACryptoServiceProvider () 
-       {
-               Dispose (false);
-       }
+namespace System.Security.Cryptography {
 
-       [MonoTODO("Persistance")]
-       private void Common (CspParameters p) 
-       {
-               rng = RandomNumberGenerator.Create ();
-               cspParams = new CspParameters ();
-               if (p == null) {
-                       // TODO: set default values (for keypair persistance)
+       public class DSACryptoServiceProvider : DSA {
+       
+               private CspParameters cspParams;
+               private RandomNumberGenerator rng;
+       
+               private bool privateKeyExportable = true;
+               private bool m_disposed = false;
+               private bool keypairGenerated = false;
+               private bool persistKey = false;
+       
+               private BigInteger p;
+               private BigInteger q;
+               private BigInteger g;
+               private BigInteger x;   // private key
+               private BigInteger y;
+               private BigInteger j;
+               private BigInteger seed;
+               private int counter;
+       
+               public DSACryptoServiceProvider () 
+               {
+                       // Here it's not clear if we need to generate a keypair
+                       // (note: MS implementation generates a keypair in this case).
+                       // However we:
+                       // (a) often use this constructor to import an existing keypair.
+                       // (b) take a LOT of time to generate the DSA group
+                       // So we'll generate the keypair only when (and if) it's being
+                       // used (or exported). This should save us a lot of time (at 
+                       // least in the unit tests).
+                       Common (null);
                }
-               else {
-                       cspParams = p;
-                       // FIXME: We'll need this to support some kind of persistance
-                       throw new NotSupportedException ("CspParameters not supported");
+       
+               public DSACryptoServiceProvider (CspParameters parameters) 
+               {
+                       Common (parameters);
+                       // no keypair generation done at this stage
                }
-               LegalKeySizesValue = new KeySizes [1];
-               LegalKeySizesValue [0] = new KeySizes (512, 1024, 64);
-       }
-
-       // generate both the group and the keypair
-       private void Generate (int keyLength) 
-       {
-               // will throw an exception is key size isn't supported
-               base.KeySize = keyLength;
-               GenerateParams (keyLength);
-               GenerateKeyPair ();
-               keypairGenerated = true;
-       }
-
-       // this part is quite fast
-       private void GenerateKeyPair () 
-       {
-               x = new BigInteger ();
-               do {
-                       // size of x (private key) isn't affected by the keysize (512-1024)
-                       x.genRandomBits (160);
+       
+               // This constructor will generate a new keypair
+               public DSACryptoServiceProvider (int dwKeySize) 
+               {
+                       // Here it's clear that we need to generate a new keypair
+                       Common (null);
+                       Generate (dwKeySize);
                }
-               while ((x == 0) || (x >= q));
-
-               // calculate the public key y = g^x % p
-               y = g.modPow (x, p);
-       }
-
-       private void add (byte[] a, byte[] b, int value) 
-       {
-               uint x = (uint) ((b [b.Length - 1] & 0xff) + value);
-
-               a [b.Length - 1] = (byte)x;
-               x >>= 8;
-
-               for (int i = b.Length - 2; i >= 0; i--) {
-                       x += (uint) (b [i] & 0xff);
-                       a [i] = (byte)x;
-                       x >>= 8;
+       
+               // This constructor will generate a new keypair
+               public DSACryptoServiceProvider (int dwKeySize, CspParameters parameters) 
+               {
+                       Common (parameters);
+                       Generate (dwKeySize);
                }
-       }
-
-       private void GenerateParams (int keyLength) 
-       {
-               byte[] seed = new byte[20];
-               byte[] part1 = new byte[20];
-               byte[] part2 = new byte[20];
-               byte[] u = new byte[20];
-
-               SHA1 sha = SHA1.Create ();
-
-               int n = (keyLength - 1) / 160;
-               byte[] w = new byte [keyLength / 8];
-               bool primesFound = false;
-               int certainty = 80; // FIPS186-2
-
-               while (!primesFound) {
+       
+               ~DSACryptoServiceProvider () 
+               {
+                       Dispose (false);
+               }
+       
+               [MonoTODO("Persistance")]
+               private void Common (CspParameters p) 
+               {
+                       rng = RandomNumberGenerator.Create ();
+                       cspParams = new CspParameters ();
+                       if (p == null) {
+                               // TODO: set default values (for keypair persistance)
+                       }
+                       else {
+                               cspParams = p;
+                               // FIXME: We'll need this to support some kind of persistance
+                               throw new NotSupportedException ("CspParameters not supported");
+                       }
+                       LegalKeySizesValue = new KeySizes [1];
+                       LegalKeySizesValue [0] = new KeySizes (512, 1024, 64);
+               }
+       
+               // generate both the group and the keypair
+               private void Generate (int keyLength) 
+               {
+                       // will throw an exception is key size isn't supported
+                       base.KeySize = keyLength;
+                       GenerateParams (keyLength);
+                       GenerateKeyPair ();
+                       keypairGenerated = true;
+               }
+       
+               // this part is quite fast
+               private void GenerateKeyPair () 
+               {
+                       x = new BigInteger ();
                        do {
-                               rng.GetBytes (seed);
-                               part1 = sha.ComputeHash (seed);
-                               Array.Copy(seed, 0, part2, 0, seed.Length);
-
-                               add (part2, seed, 1);
-
-                               part2 = sha.ComputeHash (part2);
-
-                               for (int i = 0; i != u.Length; i++) 
-                                       u [i] = (byte)(part1 [i] ^ part2 [i]);
-
-                               // first bit must be set (to respect key length)
-                               u[0] |= (byte)0x80;
-                               // last bit must be set (prime are all odds - except 2)
-                               u[19] |= (byte)0x01;
-
-                               q = new BigInteger (u);
+                               // size of x (private key) isn't affected by the keysize (512-1024)
+                               x.genRandomBits (160);
                        }
-                       while (!q.isProbablePrime (certainty));
-
-                       counter = 0;
-                       int offset = 2;
-                       while (counter < 4096) {
-                               for (int k = 0; k < n; k++) {
-                                       add(part1, seed, offset + k);
-                                       part1 = sha.ComputeHash (part1);
-                                       Array.Copy (part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length);
+                       while ((x == 0) || (x >= q));
+       
+                       // calculate the public key y = g^x % p
+                       y = g.modPow (x, p);
+               }
+       
+               private void add (byte[] a, byte[] b, int value) 
+               {
+                       uint x = (uint) ((b [b.Length - 1] & 0xff) + value);
+       
+                       a [b.Length - 1] = (byte)x;
+                       x >>= 8;
+       
+                       for (int i = b.Length - 2; i >= 0; i--) {
+                               x += (uint) (b [i] & 0xff);
+                               a [i] = (byte)x;
+                               x >>= 8;
+                       }
+               }
+       
+               private void GenerateParams (int keyLength) 
+               {
+                       byte[] seed = new byte[20];
+                       byte[] part1 = new byte[20];
+                       byte[] part2 = new byte[20];
+                       byte[] u = new byte[20];
+       
+                       SHA1 sha = SHA1.Create ();
+       
+                       int n = (keyLength - 1) / 160;
+                       byte[] w = new byte [keyLength / 8];
+                       bool primesFound = false;
+                       int certainty = 80; // FIPS186-2
+       
+                       while (!primesFound) {
+                               do {
+                                       rng.GetBytes (seed);
+                                       part1 = sha.ComputeHash (seed);
+                                       Array.Copy(seed, 0, part2, 0, seed.Length);
+       
+                                       add (part2, seed, 1);
+       
+                                       part2 = sha.ComputeHash (part2);
+       
+                                       for (int i = 0; i != u.Length; i++) 
+                                               u [i] = (byte)(part1 [i] ^ part2 [i]);
+       
+                                       // first bit must be set (to respect key length)
+                                       u[0] |= (byte)0x80;
+                                       // last bit must be set (prime are all odds - except 2)
+                                       u[19] |= (byte)0x01;
+       
+                                       q = new BigInteger (u);
                                }
-
-                               add(part1, seed, offset + n);
-                               part1 = sha.ComputeHash (part1);
-                               Array.Copy (part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length);
-
-                               w[0] |= (byte)0x80;
-                               BigInteger x = new BigInteger (w);
-
-                               BigInteger c = x % (q * 2);
-
-                               p = x - (c - 1);
-
-                               if (p.testBit ((uint)(keyLength - 1))) {
-                                       if (p.isProbablePrime (certainty)) {
-                                               primesFound = true;
-                                               break;
+                               while (!q.isProbablePrime (certainty));
+       
+                               counter = 0;
+                               int offset = 2;
+                               while (counter < 4096) {
+                                       for (int k = 0; k < n; k++) {
+                                               add(part1, seed, offset + k);
+                                               part1 = sha.ComputeHash (part1);
+                                               Array.Copy (part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length);
+                                       }
+       
+                                       add(part1, seed, offset + n);
+                                       part1 = sha.ComputeHash (part1);
+                                       Array.Copy (part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length);
+       
+                                       w[0] |= (byte)0x80;
+                                       BigInteger x = new BigInteger (w);
+       
+                                       BigInteger c = x % (q * 2);
+       
+                                       p = x - (c - 1);
+       
+                                       if (p.testBit ((uint)(keyLength - 1))) {
+                                               if (p.isProbablePrime (certainty)) {
+                                                       primesFound = true;
+                                                       break;
+                                               }
                                        }
+       
+                                       counter += 1;
+                                       offset += n + 1;
                                }
-
-                               counter += 1;
-                               offset += n + 1;
                        }
+       
+                       // calculate the generator g
+                       BigInteger pMinusOneOverQ = (p - 1) / q;
+                       for (;;) {
+                               BigInteger h = new BigInteger ();
+                               h.genRandomBits (keyLength);
+                               if ((h <= 1) || (h >= (p - 1)))
+                                       continue;
+       
+                               g = h.modPow (pMinusOneOverQ, p);
+                               if (g <= 1)
+                                       continue;
+                               break;
+                       }
+       
+                       this.seed = new BigInteger (seed);
+                       j = (p - 1) / q;
                }
-
-               // calculate the generator g
-               BigInteger pMinusOneOverQ = (p - 1) / q;
-               for (;;) {
-                       BigInteger h = new BigInteger ();
-                       h.genRandomBits (keyLength);
-                       if ((h <= 1) || (h >= (p - 1)))
-                               continue;
-
-                       g = h.modPow (pMinusOneOverQ, p);
-                       if (g <= 1)
-                               continue;
-                       break;
+       
+               [MonoTODO()]
+               private bool Validate () 
+               {
+                       // J is optional 
+                       bool okJ = ((j == 0) || (j == ((p - 1) / q)));
+                       // TODO: Validate the key parameters (P, Q, G, J) using the Seed and Counter
+                       return okJ;
                }
-
-               this.seed = new BigInteger (seed);
-               j = (p - 1) / q;
-       }
-
-       [MonoTODO()]
-       private bool Validate () 
-       {
-               // J is optional 
-               bool okJ = ((j == 0) || (j == ((p - 1) / q)));
-               // TODO: Validate the key parameters (P, Q, G, J) using the Seed and Counter
-               return okJ;
-       }
-
-       // DSA isn't used for key exchange
-       public override string KeyExchangeAlgorithm {
-               get { return ""; }
-       }
-
-       public override int KeySize {
-               get { return p.bitCount (); }
-       }
-
-       public override KeySizes[] LegalKeySizes {
-               get { return LegalKeySizesValue; }
-       }
-
-       public override string SignatureAlgorithm {
-               get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }
-       }
-
-       [MonoTODO("Persistance")]
-       public bool PersistKeyInCsp {
-               get { return persistKey; }
-               set { 
-                       persistKey = value;
-                       // FIXME: We'll need this to support some kind of persistance
-                       if (value)
-                               throw new NotSupportedException ("CspParameters not supported");
+       
+               // DSA isn't used for key exchange
+               public override string KeyExchangeAlgorithm {
+                       get { return ""; }
+               }
+       
+               public override int KeySize {
+                       get { return p.bitCount (); }
+               }
+       
+               public override KeySizes[] LegalKeySizes {
+                       get { return LegalKeySizesValue; }
                }
-       }
        
-       protected override void Dispose (bool disposing) 
-       {
-               if (!m_disposed) {
-                       // TODO: always zeroize private key
-                       if(disposing) {
-                               // TODO: Dispose managed resources
+               public override string SignatureAlgorithm {
+                       get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }
+               }
+       
+               [MonoTODO("Persistance")]
+               public bool PersistKeyInCsp {
+                       get { return persistKey; }
+                       set { 
+                               persistKey = value;
+                               // FIXME: We'll need this to support some kind of persistance
+                               if (value)
+                                       throw new NotSupportedException ("CspParameters not supported");
                        }
-         
-                       // TODO: Dispose unmanaged resources
                }
-               // call base class 
-               // no need as they all are abstract before us
-               m_disposed = true;
-       }
-
-       public override byte[] CreateSignature (byte[] rgbHash) 
-       {
-               return SignHash (rgbHash, "SHA1");
-       }
+               
+               protected override void Dispose (bool disposing) 
+               {
+                       if (!m_disposed) {
+                               // TODO: always zeroize private key
+                               if(disposing) {
+                                       // TODO: Dispose managed resources
+                               }
+                
+                               // TODO: Dispose unmanaged resources
+                       }
+                       // call base class 
+                       // no need as they all are abstract before us
+                       m_disposed = true;
+               }
+       
+               public override byte[] CreateSignature (byte[] rgbHash) 
+               {
+                       return SignHash (rgbHash, "SHA1");
+               }
+               
+               public byte[] SignData (byte[] data) 
+               {
+                       return SignData (data, 0, data.Length);
+               }
+       
+               public byte[] SignData (byte[] data, int offset, int count) 
+               {
+                       // right now only SHA1 is supported by FIPS186-2
+                       HashAlgorithm hash = SHA1.Create ();
+                       byte[] toBeSigned = hash.ComputeHash (data, offset, count);
+                       return SignHash (toBeSigned, "SHA1");
+               }
+       
+               public byte[] SignData (Stream inputStream) 
+               {
+                       // right now only SHA1 is supported by FIPS186-2
+                       HashAlgorithm hash = SHA1.Create ();
+                       byte[] toBeSigned = hash.ComputeHash (inputStream);
+                       return SignHash (toBeSigned, "SHA1");
+               }
+       
+               public byte[] SignHash (byte[] rgbHash, string str) 
+               {
+                       if (rgbHash == null)
+                               throw new ArgumentNullException ();
+                       if (x.ToString() == "0")
+                               throw new CryptographicException ("no private key available for signature");
+                       // right now only SHA1 is supported by FIPS186-2
+                       if (str.ToUpper () != "SHA1")
+                               throw new Exception (); // not documented
+                       if (rgbHash.Length != 20)
+                               throw new Exception (); // not documented
+       
+                       if (!keypairGenerated)
+                               Generate (1024);
        
-       public byte[] SignData (byte[] data) 
-       {
-               return SignData (data, 0, data.Length);
-       }
-
-       public byte[] SignData (byte[] data, int offset, int count) 
-       {
-               // right now only SHA1 is supported by FIPS186-2
-               HashAlgorithm hash = SHA1.Create ();
-               byte[] toBeSigned = hash.ComputeHash (data, offset, count);
-               return SignHash (toBeSigned, "SHA1");
-       }
-
-       public byte[] SignData (Stream inputStream) 
-       {
-               // right now only SHA1 is supported by FIPS186-2
-               HashAlgorithm hash = SHA1.Create ();
-               byte[] toBeSigned = hash.ComputeHash (inputStream);
-               return SignHash (toBeSigned, "SHA1");
-       }
-
-       public byte[] SignHash (byte[] rgbHash, string str) 
-       {
-               if (rgbHash == null)
-                       throw new ArgumentNullException ();
-               if (x.ToString() == "0")
-                       throw new CryptographicException ("no private key available for signature");
-               // right now only SHA1 is supported by FIPS186-2
-               if (str.ToUpper () != "SHA1")
-                       throw new Exception (); // not documented
-               if (rgbHash.Length != 20)
-                       throw new Exception (); // not documented
-
-               if (!keypairGenerated)
-                       Generate (1024);
-
-               BigInteger m = new BigInteger (rgbHash);
-               // (a) Select a random secret integer k; 0 < k < q.
-               BigInteger k = new BigInteger ();
-               k.genRandomBits (160);
-               while (k >= q)
-                       k.genRandomBits (160);
-               // (b) Compute r = (\v k mod p) mod q
-               BigInteger r = (g.modPow (k, p)) % q;
-               // (c) Compute k -1 mod q (e.g., using Algorithm 2.142).
-               // (d) Compute s = k -1 fh(m) +arg mod q.
-               BigInteger s = (k.modInverse (q) * (m + x * r)) % q;
-               // (e) A\92s signature for m is the pair (r; s).
-               byte[] signature = new byte [40];
-               byte[] part1 = r.getBytes ();
-               byte[] part2 = s.getBytes ();
-               // note: sometime (1/256) we may get less than 20 bytes (if first is 00)
-               int start = 20 - part1.Length;
-               Array.Copy (part1, 0, signature, start, part1.Length);
-               start = 40 - part2.Length;
-               Array.Copy (part2, 0, signature, start, part2.Length);
-               return signature;
-       }
-
-       public bool VerifyData (byte[] rgbData, byte[] rgbSignature) 
-       {
-               // signature is always 40 bytes (no matter the size of the 
-               // public key). In fact it is 2 times the size of the private
-               // key (which is 20 bytes for 512 to 1024 bits DSA keypairs)
-               if (rgbSignature.Length != 40)
-                       throw new Exception(); // not documented
-               // right now only SHA1 is supported by FIPS186-2
-               HashAlgorithm hash = SHA1.Create();
-               byte[] toBeVerified = hash.ComputeHash (rgbData);
-               return VerifyHash (toBeVerified, "SHA1", rgbSignature);
-       }
-
-       // LAMESPEC: MD5 isn't allowed with DSA
-       public bool VerifyHash (byte[] rgbHash, string str, byte[] rgbSignature) 
-       {
-               if (rgbHash == null)
-                       throw new ArgumentNullException ("rgbHash");
-               if (rgbSignature == null)
-                       throw new ArgumentNullException ("rgbSignature");
-               if (str == null)
-                       str = "SHA1"; // default value
-               if (str != "SHA1")
-                       throw new CryptographicException ();
-
-               // it would be stupid to verify a signature with a newly
-               // generated keypair - so we return false
-               if (!keypairGenerated)
-                       return false;
-
-               try {
                        BigInteger m = new BigInteger (rgbHash);
-                       byte[] half = new byte [20];
-                       Array.Copy (rgbSignature, 0, half, 0, 20);
-                       BigInteger r = new BigInteger (half);
-                       Array.Copy (rgbSignature, 20, half, 0, 20);
-                       BigInteger s = new BigInteger (half);
-
-                       if ((r < 0) || (q <= r))
-                               return false;
-
-                       if ((s < 0) || (q <= s))
-                               return false;
-
-                       BigInteger w = s.modInverse(q);
-                       BigInteger u1 = m * w % q;
-                       BigInteger u2 = r * w % q;
-
-                       u1 = g.modPow(u1, p);
-                       u2 = y.modPow(u2, p);
-
-                       BigInteger v = ((u1 * u2 % p) % q);
-                       return (v == r);
+                       // (a) Select a random secret integer k; 0 < k < q.
+                       BigInteger k = new BigInteger ();
+                       k.genRandomBits (160);
+                       while (k >= q)
+                               k.genRandomBits (160);
+                       // (b) Compute r = (g^k mod p) mod q
+                       BigInteger r = (g.modPow (k, p)) % q;
+                       // (c) Compute k -1 mod q (e.g., using Algorithm 2.142).
+                       // (d) Compute s = k -1 fh(m) +arg mod q.
+                       BigInteger s = (k.modInverse (q) * (m + x * r)) % q;
+                       // (e) A\19s signature for m is the pair (r; s).
+                       byte[] signature = new byte [40];
+                       byte[] part1 = r.getBytes ();
+                       byte[] part2 = s.getBytes ();
+                       // note: sometime (1/256) we may get less than 20 bytes (if first is 00)
+                       int start = 20 - part1.Length;
+                       Array.Copy (part1, 0, signature, start, part1.Length);
+                       start = 40 - part2.Length;
+                       Array.Copy (part2, 0, signature, start, part2.Length);
+                       return signature;
                }
-               catch {
-                       throw new CryptographicException ();
+       
+               public bool VerifyData (byte[] rgbData, byte[] rgbSignature) 
+               {
+                       // signature is always 40 bytes (no matter the size of the 
+                       // public key). In fact it is 2 times the size of the private
+                       // key (which is 20 bytes for 512 to 1024 bits DSA keypairs)
+                       if (rgbSignature.Length != 40)
+                               throw new Exception(); // not documented
+                       // right now only SHA1 is supported by FIPS186-2
+                       HashAlgorithm hash = SHA1.Create();
+                       byte[] toBeVerified = hash.ComputeHash (rgbData);
+                       return VerifyHash (toBeVerified, "SHA1", rgbSignature);
                }
-       }
-
-       public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) 
-       {
-               return VerifyHash (rgbHash, "SHA1", rgbSignature);
-       }
-
-       private byte[] NormalizeArray (byte[] array) 
-       {
-               int n = (array.Length % 4);
-               if (n > 0) {
-                       byte[] temp = new byte [array.Length + 4 - n];
-                       Array.Copy (array, 0, temp, (4 - n), array.Length);
-                       return temp;
+       
+               // LAMESPEC: MD5 isn't allowed with DSA
+               public bool VerifyHash (byte[] rgbHash, string str, byte[] rgbSignature) 
+               {
+                       if (rgbHash == null)
+                               throw new ArgumentNullException ("rgbHash");
+                       if (rgbSignature == null)
+                               throw new ArgumentNullException ("rgbSignature");
+                       if (str == null)
+                               str = "SHA1"; // default value
+                       if (str != "SHA1")
+                               throw new CryptographicException ();
+       
+                       // it would be stupid to verify a signature with a newly
+                       // generated keypair - so we return false
+                       if (!keypairGenerated)
+                               return false;
+       
+                       try {
+                               BigInteger m = new BigInteger (rgbHash);
+                               byte[] half = new byte [20];
+                               Array.Copy (rgbSignature, 0, half, 0, 20);
+                               BigInteger r = new BigInteger (half);
+                               Array.Copy (rgbSignature, 20, half, 0, 20);
+                               BigInteger s = new BigInteger (half);
+       
+                               if ((r < 0) || (q <= r))
+                                       return false;
+       
+                               if ((s < 0) || (q <= s))
+                                       return false;
+       
+                               BigInteger w = s.modInverse(q);
+                               BigInteger u1 = m * w % q;
+                               BigInteger u2 = r * w % q;
+       
+                               u1 = g.modPow(u1, p);
+                               u2 = y.modPow(u2, p);
+       
+                               BigInteger v = ((u1 * u2 % p) % q);
+                               return (v == r);
+                       }
+                       catch {
+                               throw new CryptographicException ();
+                       }
                }
-               else
-                       return array;
-       }
-
-       public override DSAParameters ExportParameters (bool includePrivateParameters) 
-       {
-               if ((includePrivateParameters) && (!privateKeyExportable))
-                       throw new CryptographicException ("cannot export private key");
-               if (!keypairGenerated)
-                       Generate (1024);
-
-               DSAParameters param = new DSAParameters();
-               // all parameters must be in multiple of 4 bytes arrays
-               // this isn't (generally) a problem for most of the parameters
-               // except for J (but we won't take a chance)
-               param.P = NormalizeArray (p.getBytes ());
-               param.Q = NormalizeArray (q.getBytes ());
-               param.G = NormalizeArray (g.getBytes ());
-               param.Y = NormalizeArray (y.getBytes ());
-               param.J = NormalizeArray (j.getBytes ());
-               if (seed != 0) {
-                       param.Seed = NormalizeArray (seed.getBytes ());
-                       param.Counter = counter;
+       
+               public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) 
+               {
+                       return VerifyHash (rgbHash, "SHA1", rgbSignature);
                }
-               if (includePrivateParameters) {
-                       byte[] privateKey = x.getBytes ();
-                       if (privateKey.Length == 20) {
-                               param.X = NormalizeArray (privateKey);
+       
+               private byte[] NormalizeArray (byte[] array) 
+               {
+                       int n = (array.Length % 4);
+                       if (n > 0) {
+                               byte[] temp = new byte [array.Length + 4 - n];
+                               Array.Copy (array, 0, temp, (4 - n), array.Length);
+                               return temp;
                        }
+                       else
+                               return array;
                }
-               return param;
-       }
-
-       public override void ImportParameters (DSAParameters parameters) 
-       {
-               // if missing "mandatory" parameters
-               if ((parameters.P == null) || (parameters.Q == null) || (parameters.G == null) || (parameters.Y == null))
-                       throw new CryptographicException ();
-
-               p = new BigInteger (parameters.P);
-               q = new BigInteger (parameters.Q);
-               g = new BigInteger (parameters.G);
-               y = new BigInteger (parameters.Y);
-               // optional parameter - private key
-               if (parameters.X != null)
-                       x = new BigInteger (parameters.X);
-               else
-                       x = new BigInteger (0);
-               // optional parameter - pre-computation
-               if (parameters.J != null)
-                       j = new BigInteger (parameters.J);
-               else
-                       j = (p - 1) / q;
-               // optional - seed and counter must both be present (or absent)
-               if (parameters.Seed != null) {
-                       seed = new BigInteger (parameters.Seed);
-                       counter = parameters.Counter;
+       
+               public override DSAParameters ExportParameters (bool includePrivateParameters) 
+               {
+                       if ((includePrivateParameters) && (!privateKeyExportable))
+                               throw new CryptographicException ("cannot export private key");
+                       if (!keypairGenerated)
+                               Generate (1024);
+       
+                       DSAParameters param = new DSAParameters();
+                       // all parameters must be in multiple of 4 bytes arrays
+                       // this isn't (generally) a problem for most of the parameters
+                       // except for J (but we won't take a chance)
+                       param.P = NormalizeArray (p.getBytes ());
+                       param.Q = NormalizeArray (q.getBytes ());
+                       param.G = NormalizeArray (g.getBytes ());
+                       param.Y = NormalizeArray (y.getBytes ());
+                       param.J = NormalizeArray (j.getBytes ());
+                       if (seed != 0) {
+                               param.Seed = NormalizeArray (seed.getBytes ());
+                               param.Counter = counter;
+                       }
+                       if (includePrivateParameters) {
+                               byte[] privateKey = x.getBytes ();
+                               if (privateKey.Length == 20) {
+                                       param.X = NormalizeArray (privateKey);
+                               }
+                       }
+                       return param;
+               }
+       
+               public override void ImportParameters (DSAParameters parameters) 
+               {
+                       // if missing "mandatory" parameters
+                       if ((parameters.P == null) || (parameters.Q == null) || (parameters.G == null) || (parameters.Y == null))
+                               throw new CryptographicException ();
+       
+                       p = new BigInteger (parameters.P);
+                       q = new BigInteger (parameters.Q);
+                       g = new BigInteger (parameters.G);
+                       y = new BigInteger (parameters.Y);
+                       // optional parameter - private key
+                       if (parameters.X != null)
+                               x = new BigInteger (parameters.X);
+                       else
+                               x = new BigInteger (0);
+                       // optional parameter - pre-computation
+                       if (parameters.J != null)
+                               j = new BigInteger (parameters.J);
+                       else
+                               j = (p - 1) / q;
+                       // optional - seed and counter must both be present (or absent)
+                       if (parameters.Seed != null) {
+                               seed = new BigInteger (parameters.Seed);
+                               counter = parameters.Counter;
+                       }
+                       else
+                               seed = new BigInteger (0);
+       
+                       // we now have a keypair
+                       keypairGenerated = true;
                }
-               else
-                       seed = new BigInteger (0);
-
-               // we now have a keypair
-               keypairGenerated = true;
        }
 }
-
-}
index 71294a57cf0044f29a425787b9381d7bdc7719cc..97ec3b67d3114d97177abba7b370a9c82af96bda 100644 (file)
 using System;
 using System.IO;
 
-namespace System.Security.Cryptography {
-
-// References:
-// a.  FIPS PUB 198: The Keyed-Hash Message Authentication Code (HMAC), 2002 March.
-//     http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
-// b.  Internet RFC 2104, HMAC, Keyed-Hashing for Message Authentication
-//     (include C source for HMAC-MD5)
-//     http://www.ietf.org/rfc/rfc2104.txt
-// c.  IETF RFC2202: Test Cases for HMAC-MD5 and HMAC-SHA-1
-//     (include C source for HMAC-MD5 and HAMAC-SHA1)
-//     http://www.ietf.org/rfc/rfc2202.txt
-// d.  ANSI X9.71, Keyed Hash Message Authentication Code.
-//     not free :-(
-//     http://webstore.ansi.org/ansidocstore/product.asp?sku=ANSI+X9%2E71%2D2000
-
-// Generic HMAC mechanisms - most of HMAC work is done in here.
-// It should work with any hash function e.g. MD5 for HMACMD5 (RFC2104)
-internal class HMACAlgorithm {
-       private byte[] key;
-       private byte[] hash;
-       private HashAlgorithm algo;
-       private string hashName;
-       private BlockProcessor block;
-
-       public HMACAlgorithm (string algoName)
-       {
-               CreateHash (algoName);
-       }
-
-       ~HMACAlgorithm () 
-       {
-               Dispose ();
-       }
-
-       private void CreateHash (string algoName) 
-       {
-               algo = HashAlgorithm.Create (algoName);
-               hashName = algoName;
-               block = new BlockProcessor (algo, 8);
-       }
+using Mono.Security.Cryptography;
 
-       public void Dispose () 
-       {
-               if (key != null)
-                       Array.Clear (key, 0, key.Length);
-       }
-
-       public HashAlgorithm Algo {
-               get { return algo; }
-       }
-
-       public string HashName {
-               get { return hashName; }
-               set { CreateHash (value); }
-       }
+namespace System.Security.Cryptography {
 
-       public byte[] Key {
-               get { return key; }
-               set {
-                       if ((value != null) && (value.Length > 64))
-                               key = algo.ComputeHash (value);
-                       else
-                               key = (byte[]) value.Clone();
+       // References:
+       // a.   FIPS PUB 198: The Keyed-Hash Message Authentication Code (HMAC), 2002 March.
+       //      http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
+       // b.   Internet RFC 2104, HMAC, Keyed-Hashing for Message Authentication
+       //      (include C source for HMAC-MD5)
+       //      http://www.ietf.org/rfc/rfc2104.txt
+       // c.   IETF RFC2202: Test Cases for HMAC-MD5 and HMAC-SHA-1
+       //      (include C source for HMAC-MD5 and HAMAC-SHA1)
+       //      http://www.ietf.org/rfc/rfc2202.txt
+       // d.   ANSI X9.71, Keyed Hash Message Authentication Code.
+       //      not free :-(
+       //      http://webstore.ansi.org/ansidocstore/product.asp?sku=ANSI+X9%2E71%2D2000
+       
+       public class HMACSHA1: KeyedHashAlgorithm {
+               private HMACAlgorithm hmac;
+               private bool m_disposed;
+       
+               public HMACSHA1 () : this (KeyBuilder.Key (8)) {}
+       
+               public HMACSHA1 (byte[] rgbKey) : base ()
+               {
+                       hmac = new HMACAlgorithm ("SHA1");
+                       HashSizeValue = 160;
+                       Key = rgbKey;
+                       m_disposed = false;
                }
-       }
-
-       public void Initialize () 
-       {
-               hash = null;
-               block.Initialize ();
-               byte[] buf = KeySetup (key, 0x36);
-               algo.Initialize ();
-               block.Core (buf);
-               // zeroize key
-               Array.Clear (buf, 0, buf.Length);
-       }
-
-       private byte[] KeySetup (byte[] key, byte padding) 
-       {
-               byte[] buf = new byte [64];
-
-               for (int i = 0; i < key.Length; ++i)
-                       buf [i] = (byte) ((byte) key [i] ^ padding);
-
-               for (int i = key.Length; i < 64; ++i)
-                       buf [i] = padding;
-               
-               return buf;
-       }
-
-       public void Core (byte[] rgb, int ib, int cb) 
-       {
-               block.Core (rgb, ib, cb);
-       }
-
-       public byte[] Final () 
-       {
-               block.Final ();
-               byte[] intermediate = algo.Hash;
-
-               byte[] buf = KeySetup (key, 0x5C);
-               algo.Initialize ();
-               algo.TransformBlock (buf, 0, buf.Length, buf, 0);
-               algo.TransformFinalBlock (intermediate, 0, intermediate.Length);
-               hash = algo.Hash;
-               algo.Clear ();
-               // zeroize sensitive data
-               Array.Clear (buf, 0, buf.Length);       
-               Array.Clear (intermediate, 0, intermediate.Length);
-               return hash;
-       }
-}
-
-public class HMACSHA1: KeyedHashAlgorithm {
-       private HMACAlgorithm hmac;
-       private bool m_disposed;
-
-       public HMACSHA1 () : this (KeyBuilder.Key (8)) {}
-
-       public HMACSHA1 (byte[] rgbKey) : base ()
-       {
-               hmac = new HMACAlgorithm ("SHA1");
-               HashSizeValue = 160;
-               Key = rgbKey;
-               m_disposed = false;
-       }
-
-       ~HMACSHA1 () 
-       {
-               Dispose (false);
-       }
-
-       public override byte[] Key {
-               get { return base.Key; }
-               set { 
-                       hmac.Key = value; 
-                       base.Key = value;
+       
+               ~HMACSHA1 () 
+               {
+                       Dispose (false);
                }
-       } 
-
-       public string HashName {
-               get { return hmac.HashName; }
-               set { 
-                       // only if its not too late for a change
-                       if (State == 0)
-                               hmac.HashName = value; 
+       
+               public override byte[] Key {
+                       get { return base.Key; }
+                       set { 
+                               hmac.Key = value; 
+                               base.Key = value;
+                       }
+               } 
+       
+               public string HashName {
+                       get { return hmac.HashName; }
+                       set { 
+                               // only if its not too late for a change
+                               if (State == 0)
+                                       hmac.HashName = value; 
+                       }
                }
-       }
-
-       protected override void Dispose (bool disposing) 
-       {
-               if (!m_disposed) {
-                       if (hmac != null)
-                               hmac.Dispose();
-                       base.Dispose (disposing);
-                       m_disposed = true;
+       
+               protected override void Dispose (bool disposing) 
+               {
+                       if (!m_disposed) {
+                               if (hmac != null)
+                                       hmac.Dispose();
+                               base.Dispose (disposing);
+                               m_disposed = true;
+                       }
                }
-       }
-
-       public override void Initialize ()
-       {
-               if (m_disposed)
-                       throw new ObjectDisposedException ("HMACSHA1");
-               // let us throw an exception if hash name is invalid
-               // for HMACSHA1 (obviously this can't be done by the 
-               // generic HMAC class) 
-               if (! (hmac.Algo is SHA1))
-                       throw new InvalidCastException ();
-               State = 0;
-               hmac.Initialize ();
-       }
-
-        protected override void HashCore (byte[] rgb, int ib, int cb)
-       {
-               if (m_disposed)
-                       throw new ObjectDisposedException ("HMACSHA1");
-               if (State == 0) {
-                       Initialize ();
-                       State = 1;
+       
+               public override void Initialize ()
+               {
+                       if (m_disposed)
+                               throw new ObjectDisposedException ("HMACSHA1");
+                       // let us throw an exception if hash name is invalid
+                       // for HMACSHA1 (obviously this can't be done by the 
+                       // generic HMAC class) 
+                       if (! (hmac.Algo is SHA1))
+                               throw new InvalidCastException ();
+                       State = 0;
+                       hmac.Initialize ();
+               }
+       
+               protected override void HashCore (byte[] rgb, int ib, int cb)
+               {
+                       if (m_disposed)
+                               throw new ObjectDisposedException ("HMACSHA1");
+                       if (State == 0) {
+                               Initialize ();
+                               State = 1;
+                       }
+                       hmac.Core (rgb, ib, cb);
+               }
+       
+               protected override byte[] HashFinal ()
+               {
+                       if (m_disposed)
+                               throw new ObjectDisposedException ("HMACSHA1");
+                       State = 0;
+                       return hmac.Final ();
                }
-               hmac.Core (rgb, ib, cb);
-       }
-
-       protected override byte[] HashFinal ()
-       {
-               if (m_disposed)
-                       throw new ObjectDisposedException ("HMACSHA1");
-               State = 0;
-               return hmac.Final ();
        }
-}
-
 }
\ No newline at end of file
index a64d8dd9cf2d3ed4a1aa82e1e3edd904925622e5..9d73e5f18af75fed6a2bd21b2dfd4db6a8520abc 100644 (file)
 
 using System;
 
-namespace System.Security.Cryptography {
-
-// References:
-// a.  FIPS PUB 81: DES MODES OF OPERATION 
-//     MAC: Appendix F (MACDES not MACTripleDES but close enough ;-)
-//     http://www.itl.nist.gov/fipspubs/fip81.htm
+using Mono.Security.Cryptography;
 
-// Generic MAC mechanims - most of the work is done in here
-// It should work with any symmetric algorithm function e.g. DES for MACDES (fips81)
-internal class MACAlgorithm {
-       private SymmetricAlgorithm algo;
-       private ICryptoTransform enc;
-       private BlockProcessor block;
-
-       public MACAlgorithm (SymmetricAlgorithm algorithm)
-       {
-               algo = (SymmetricAlgorithm) algorithm;
-               algo.Mode = CipherMode.CBC;
-               algo.Padding = PaddingMode.Zeros;
-               algo.IV = new byte [(algo.BlockSize >> 3)];
-       }
+namespace System.Security.Cryptography {
 
-       public void Initialize (byte[] key) 
-       {
-               algo.Key = key;
-               // note: the encryptor transform amy be reused - see Final
-               if (enc == null) {
-                       enc = algo.CreateEncryptor ();
-                       block = new BlockProcessor (enc);
-               }
-               block.Initialize ();
-       }
+       // References:
+       // a.   FIPS PUB 81: DES MODES OF OPERATION 
+       //      MAC: Appendix F (MACDES not MACTripleDES but close enough ;-)
+       //      http://www.itl.nist.gov/fipspubs/fip81.htm
        
-       public void Core (byte[] rgb, int ib, int cb) 
-       {
-               block.Core (rgb, ib, cb);
-       }
-
-       public byte[] Final () 
-       {
-               byte[] mac = block.Final ();
-               if (!enc.CanReuseTransform) {
-                       enc.Dispose();
-                       enc = null;
+       // LAMESPEC: MACTripleDES == MAC-CBC using TripleDES (not MAC-CFB).
+       public class MACTripleDES: KeyedHashAlgorithm {
+       
+               private TripleDES tdes;
+               private MACAlgorithm mac;
+               private bool m_disposed;
+       
+               public MACTripleDES ()
+               {
+                       Setup ("TripleDES", null);
                }
-               return mac;
-       }
-}
-
-// LAMESPEC: MACTripleDES == MAC-CBC using TripleDES (not MAC-CFB).
-public class MACTripleDES: KeyedHashAlgorithm {
-
-       private TripleDES tdes;
-       private MACAlgorithm mac;
-       private bool m_disposed;
-
-       public MACTripleDES ()
-       {
-               Setup ("TripleDES", null);
-       }
-
-       public MACTripleDES (byte[] rgbKey)
-       {
-               if (rgbKey == null)
-                       throw new ArgumentNullException ("rgbKey");
-               Setup ("TripleDES", rgbKey);
-       }
-
-       public MACTripleDES (string strTripleDES, byte[] rgbKey) 
-       {
-               if (rgbKey == null)
-                       throw new ArgumentNullException ("rgbKey");
-               if (strTripleDES == null)
+       
+               public MACTripleDES (byte[] rgbKey)
+               {
+                       if (rgbKey == null)
+                               throw new ArgumentNullException ("rgbKey");
                        Setup ("TripleDES", rgbKey);
-               else
-                       Setup (strTripleDES, rgbKey);
-       }
-
-       private void Setup (string strTripleDES, byte[] rgbKey) 
-       {
-               tdes = TripleDES.Create (strTripleDES);
-               // if rgbKey is null we keep the randomly generated key
-               if (rgbKey != null) {
-                       // this way we get the TripleDES key validation (like weak
-                       // and semi-weak keys)
-                       tdes.Key = rgbKey;
                }
-               HashSizeValue = tdes.BlockSize;
-               // we use Key property to get the additional validations 
-               // (from KeyedHashAlgorithm ancestor)
-               Key = tdes.Key;
-               mac = new MACAlgorithm (tdes);
-               m_disposed = false;
-       }
-
-       ~MACTripleDES () 
-       {
-               Dispose (false);
-       }
-
-       protected override void Dispose (bool disposing) 
-       {
-               if (!m_disposed) {
-                       // note: we ALWAYS zeroize keys (disposing or not)
-
-                       // clear our copy of the secret key
-                       if (KeyValue != null)
-                               Array.Clear (KeyValue, 0, KeyValue.Length);
-                       // clear the secret key (inside TripleDES)
-                       if (tdes != null)
-                               tdes.Clear ();
-
-                       if (disposing) {
-                               // disposed managed stuff
-                               KeyValue = null;
-                               tdes = null;
+       
+               public MACTripleDES (string strTripleDES, byte[] rgbKey) 
+               {
+                       if (rgbKey == null)
+                               throw new ArgumentNullException ("rgbKey");
+                       if (strTripleDES == null)
+                               Setup ("TripleDES", rgbKey);
+                       else
+                               Setup (strTripleDES, rgbKey);
+               }
+       
+               private void Setup (string strTripleDES, byte[] rgbKey) 
+               {
+                       tdes = TripleDES.Create (strTripleDES);
+                       // if rgbKey is null we keep the randomly generated key
+                       if (rgbKey != null) {
+                               // this way we get the TripleDES key validation (like weak
+                               // and semi-weak keys)
+                               tdes.Key = rgbKey;
                        }
-                       // ancestor
-                       base.Dispose (disposing);
-                       m_disposed = true;
+                       HashSizeValue = tdes.BlockSize;
+                       // we use Key property to get the additional validations 
+                       // (from KeyedHashAlgorithm ancestor)
+                       Key = tdes.Key;
+                       mac = new MACAlgorithm (tdes);
+                       m_disposed = false;
                }
-       }
-
-       public override void Initialize () 
-       {
-               if (m_disposed)
-                       throw new ObjectDisposedException ("MACTripleDES");
-               State = 0;
-               mac.Initialize (KeyValue);
-       }
-
-       protected override void HashCore (byte[] rgb, int ib, int cb) 
-       {
-               if (m_disposed)
-                       throw new ObjectDisposedException ("MACTripleDES");
-               if (State == 0) {
-                       Initialize ();
-                       State = 1;
+       
+               ~MACTripleDES () 
+               {
+                       Dispose (false);
+               }
+       
+               protected override void Dispose (bool disposing) 
+               {
+                       if (!m_disposed) {
+                               // note: we ALWAYS zeroize keys (disposing or not)
+       
+                               // clear our copy of the secret key
+                               if (KeyValue != null)
+                                       Array.Clear (KeyValue, 0, KeyValue.Length);
+                               // clear the secret key (inside TripleDES)
+                               if (tdes != null)
+                                       tdes.Clear ();
+       
+                               if (disposing) {
+                                       // disposed managed stuff
+                                       KeyValue = null;
+                                       tdes = null;
+                               }
+                               // ancestor
+                               base.Dispose (disposing);
+                               m_disposed = true;
+                       }
+               }
+       
+               public override void Initialize () 
+               {
+                       if (m_disposed)
+                               throw new ObjectDisposedException ("MACTripleDES");
+                       State = 0;
+                       mac.Initialize (KeyValue);
+               }
+       
+               protected override void HashCore (byte[] rgb, int ib, int cb) 
+               {
+                       if (m_disposed)
+                               throw new ObjectDisposedException ("MACTripleDES");
+                       if (State == 0) {
+                               Initialize ();
+                               State = 1;
+                       }
+                       mac.Core (rgb, ib, cb);
+               }
+       
+               protected override byte[] HashFinal () 
+               {
+                       if (m_disposed)
+                               throw new ObjectDisposedException ("MACTripleDES");
+                       State = 0;
+                       return mac.Final ();
                }
-               mac.Core (rgb, ib, cb);
-       }
-
-       protected override byte[] HashFinal () 
-       {
-               if (m_disposed)
-                       throw new ObjectDisposedException ("MACTripleDES");
-               State = 0;
-               return mac.Final ();
        }
-}
-
 }
\ No newline at end of file
index c56fa12d38f79f31b1fa7f8d04b4326a1bcce7d9..a694c200204e59ab1917103d793fd67545ad0a38 100644 (file)
@@ -8,38 +8,38 @@
 //
 
 using System;
-using System.Security.Cryptography;
+using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography {
 
-// References:
-// a.  PKCS#1: RSA Cryptography Standard 
-//     http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/index.html
-
-public class PKCS1MaskGenerationMethod : MaskGenerationMethod {
-       private string hashName;
-
-       public PKCS1MaskGenerationMethod()
-       {
-               hashName = "SHA1";
-       }
-
-       public string HashName 
-       {
-               get { return hashName; }
-               set { 
-                       if (value == null)
-                               hashName = "SHA1";
-                       else
-                               hashName = value; 
+       // References:
+       // a.   PKCS#1: RSA Cryptography Standard 
+       //      http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/index.html
+       
+       public class PKCS1MaskGenerationMethod : MaskGenerationMethod {
+
+               private string hashName;
+       
+               public PKCS1MaskGenerationMethod()
+               {
+                       hashName = "SHA1";
+               }
+       
+               public string HashName 
+               {
+                       get { return hashName; }
+                       set { 
+                               if (value == null)
+                                       hashName = "SHA1";
+                               else
+                                       hashName = value; 
+                       }
+               }
+       
+               public override byte[] GenerateMask (byte[] mgfSeed, int maskLen)
+               {
+                       HashAlgorithm hash = HashAlgorithm.Create (hashName);
+                       return PKCS1.MGF1 (hash, mgfSeed, maskLen);
                }
        }
-
-       public override byte[] GenerateMask (byte[] mgfSeed, int maskLen)
-       {
-               HashAlgorithm hash = HashAlgorithm.Create (hashName);
-               return PKCS1.MGF1 (hash, mgfSeed, maskLen);
-       }
-}
-
 }
index 169035eed44076c6e601c69f5fe7b0b6a86de032..ffb11d85b0c0bed5d121bcb32ef23d7168d7bc70 100644 (file)
 //          
 
 using System;
+using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography {
 
-// References:
-// a.  IETF RFC2286: A Description of the RC2(r) Encryption Algorithm
-//     http://www.ietf.org/rfc/rfc2268.txt
-
-public sealed class RC2CryptoServiceProvider : RC2 {
-
-       public RC2CryptoServiceProvider() {}
-
-       // included to (exactly) match corlib
-       public override int EffectiveKeySize {
-               get { return base.EffectiveKeySize; }
-               set { base.EffectiveKeySize = value; }
-       }
-
-       public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
-       {
-               Key = rgbKey;
-               IV = rgbIV;
-               return new RC2Transform (this, false);
-       }
-
-       public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
-       {
-               Key = rgbKey;
-               IV = rgbIV;
-               return new RC2Transform (this, true);
-       }
-
-       public override void GenerateIV ()
-       {
-               IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
-       }
-
-       public override void GenerateKey ()
-       {
-               KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
-       }
-}
-
-internal class RC2Transform : SymmetricTransform {
-
-       private UInt16 R0, R1, R2, R3;  // state
-       private UInt16[] K;             // expanded key
-       private int j;                  // Key indexer
-
-       public RC2Transform (RC2 rc2Algo, bool encryption) : base (rc2Algo, encryption, rc2Algo.IV)
-       {
-               byte[] key = rc2Algo.Key;
-               int t1 = rc2Algo.EffectiveKeySize;
-               // Expand key into a byte array, then convert to word
-               // array since we always access the key in 16bit chunks.
-               byte[] L = new byte [128];
-
-               int t = key.Length;
-               int t8 = ((t1 + 7) >> 3); // divide by 8
-               int tm = 255 % (2 << (8 + t1 - (t8 << 3) - 1));
-
-               for (int i=0; i < t; i++)
-                       L [i] = key [i];
-               for (int i=t; i < 128; i++) 
-                       L [i] = (byte) (pitable [(L [i-1] + L [i-t]) & 0xff]);
-
-               L [128-t8] = pitable [L [128-t8] & tm];
-
-               for (int i=127-t8; i >= 0; i--) 
-                       L [i] = pitable [L [i+1] ^ L [i+t8]];
-
-               K = new UInt16 [64];
-               int pos = 0;
-               for (int i=0; i < 64; i++) 
-                       K [i] = (UInt16) (L [pos++] + (L [pos++] << 8));
+       // References:
+       // a.   IETF RFC2286: A Description of the RC2(r) Encryption Algorithm
+       //      http://www.ietf.org/rfc/rfc2268.txt
+       
+       public sealed class RC2CryptoServiceProvider : RC2 {
+       
+               public RC2CryptoServiceProvider() {}
+       
+               // included to (exactly) match corlib
+               public override int EffectiveKeySize {
+                       get { return base.EffectiveKeySize; }
+                       set { base.EffectiveKeySize = value; }
+               }
+       
+               public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
+               {
+                       Key = rgbKey;
+                       IV = rgbIV;
+                       return new RC2Transform (this, false);
+               }
+       
+               public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
+               {
+                       Key = rgbKey;
+                       IV = rgbIV;
+                       return new RC2Transform (this, true);
+               }
+       
+               public override void GenerateIV ()
+               {
+                       IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
+               }
+       
+               public override void GenerateKey ()
+               {
+                       KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
+               }
        }
-
-       protected override void ECB (byte[] input, byte[] output) 
-       {
-               // unrolled loop, eliminated mul
-               R0 = (UInt16) (input [0] | (input [1] << 8));
-               R1 = (UInt16) (input [2] | (input [3] << 8));
-               R2 = (UInt16) (input [4] | (input [5] << 8));
-               R3 = (UInt16) (input [6] | (input [7] << 8));
-
-               if (encrypt) {
-                       j = 0;
-                       // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix();
-                       while (j <= 16) {
-                               R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
-                               R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
-
-                               R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
-                               R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
-
-                               R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
-                               R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
-
-                               R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
-                               R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
-                       }
-
-                       // inline Mash(); j == 20
-                       R0 += K [R3 & 63];
-                       R1 += K [R0 & 63];
-                       R2 += K [R1 & 63];
-                       R3 += K [R2 & 63];
-
-                       // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix(); Mix();
-                       while (j <= 40) {
-                               R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
-                               R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
-
-                               R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
-                               R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
-
-                               R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
-                               R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
-
-                               R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
-                               R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
-                       }
-
-                       // inline Mash(); j == 44
-                       R0 += K [R3 & 63];
-                       R1 += K [R0 & 63];
-                       R2 += K [R1 & 63];
-                       R3 += K [R2 & 63];
-
-                       // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix();
-                       while (j < 64) {
-                               R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
-                               R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
-
-                               R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
-                               R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
-
-                               R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
-                               R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
-
-                               R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
-                               R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
-                       }
-               } 
-               else {
-                       j = 63;
-                       // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix();
-                       while (j >= 44) {
-                               R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
-                               R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
-
-                               R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
-                               R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
-
-                               R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
-                               R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
-
-                               R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
-                               R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
-                       }
-
-                       // inline RMash();
-                       R3 -= K [R2 & 63];
-                       R2 -= K [R1 & 63];
-                       R1 -= K [R0 & 63];
-                       R0 -= K [R3 & 63];
-
-                       // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix(); RMix();
-                       while (j >= 20) {
-                               R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
-                               R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
-
-                               R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
-                               R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
-
-                               R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
-                               R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
-
-                               R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
-                               R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
-                       }
-
-                       // inline RMash();
-                       R3 -= K [R2 & 63];
-                       R2 -= K [R1 & 63];
-                       R1 -= K [R0 & 63];
-                       R0 -= K [R3 & 63];
-
-                       // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix();
-                       while (j >= 0) {
-                               R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
-                               R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
-
-                               R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
-                               R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
-
-                               R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
-                               R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
-
-                               R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
-                               R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
+       
+       internal class RC2Transform : SymmetricTransform {
+       
+               private UInt16 R0, R1, R2, R3;  // state
+               private UInt16[] K;             // expanded key
+               private int j;                  // Key indexer
+       
+               public RC2Transform (RC2 rc2Algo, bool encryption) : base (rc2Algo, encryption, rc2Algo.IV)
+               {
+                       byte[] key = rc2Algo.Key;
+                       int t1 = rc2Algo.EffectiveKeySize;
+                       // Expand key into a byte array, then convert to word
+                       // array since we always access the key in 16bit chunks.
+                       byte[] L = new byte [128];
+       
+                       int t = key.Length;
+                       int t8 = ((t1 + 7) >> 3); // divide by 8
+                       int tm = 255 % (2 << (8 + t1 - (t8 << 3) - 1));
+       
+                       for (int i=0; i < t; i++)
+                               L [i] = key [i];
+                       for (int i=t; i < 128; i++) 
+                               L [i] = (byte) (pitable [(L [i-1] + L [i-t]) & 0xff]);
+       
+                       L [128-t8] = pitable [L [128-t8] & tm];
+       
+                       for (int i=127-t8; i >= 0; i--) 
+                               L [i] = pitable [L [i+1] ^ L [i+t8]];
+       
+                       K = new UInt16 [64];
+                       int pos = 0;
+                       for (int i=0; i < 64; i++) 
+                               K [i] = (UInt16) (L [pos++] + (L [pos++] << 8));
+               }
+       
+               protected override void ECB (byte[] input, byte[] output) 
+               {
+                       // unrolled loop, eliminated mul
+                       R0 = (UInt16) (input [0] | (input [1] << 8));
+                       R1 = (UInt16) (input [2] | (input [3] << 8));
+                       R2 = (UInt16) (input [4] | (input [5] << 8));
+                       R3 = (UInt16) (input [6] | (input [7] << 8));
+       
+                       if (encrypt) {
+                               j = 0;
+                               // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix();
+                               while (j <= 16) {
+                                       R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
+                                       R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
+       
+                                       R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
+                                       R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
+       
+                                       R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
+                                       R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
+       
+                                       R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
+                                       R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
+                               }
+       
+                               // inline Mash(); j == 20
+                               R0 += K [R3 & 63];
+                               R1 += K [R0 & 63];
+                               R2 += K [R1 & 63];
+                               R3 += K [R2 & 63];
+       
+                               // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix(); Mix();
+                               while (j <= 40) {
+                                       R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
+                                       R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
+       
+                                       R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
+                                       R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
+       
+                                       R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
+                                       R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
+       
+                                       R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
+                                       R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
+                               }
+       
+                               // inline Mash(); j == 44
+                               R0 += K [R3 & 63];
+                               R1 += K [R0 & 63];
+                               R2 += K [R1 & 63];
+                               R3 += K [R2 & 63];
+       
+                               // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix();
+                               while (j < 64) {
+                                       R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
+                                       R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
+       
+                                       R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
+                                       R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
+       
+                                       R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
+                                       R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
+       
+                                       R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
+                                       R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
+                               }
+                       } 
+                       else {
+                               j = 63;
+                               // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix();
+                               while (j >= 44) {
+                                       R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
+                                       R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
+       
+                                       R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
+                                       R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
+       
+                                       R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
+                                       R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
+       
+                                       R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
+                                       R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
+                               }
+       
+                               // inline RMash();
+                               R3 -= K [R2 & 63];
+                               R2 -= K [R1 & 63];
+                               R1 -= K [R0 & 63];
+                               R0 -= K [R3 & 63];
+       
+                               // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix(); RMix();
+                               while (j >= 20) {
+                                       R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
+                                       R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
+       
+                                       R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
+                                       R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
+       
+                                       R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
+                                       R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
+       
+                                       R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
+                                       R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
+                               }
+       
+                               // inline RMash();
+                               R3 -= K [R2 & 63];
+                               R2 -= K [R1 & 63];
+                               R1 -= K [R0 & 63];
+                               R0 -= K [R3 & 63];
+       
+                               // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix();
+                               while (j >= 0) {
+                                       R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
+                                       R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
+       
+                                       R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
+                                       R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
+       
+                                       R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
+                                       R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
+       
+                                       R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
+                                       R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
+                               }
                        }
+       
+                       // unrolled loop
+                       output[0] = (byte) R0;
+                       output[1] = (byte) (R0 >> 8);
+                       output[2] = (byte) R1;
+                       output[3] = (byte) (R1 >> 8);
+                       output[4] = (byte) R2;
+                       output[5] = (byte) (R2 >> 8);
+                       output[6] = (byte) R3;
+                       output[7] = (byte) (R3 >> 8);
                }
-
-               // unrolled loop
-               output[0] = (byte) R0;
-               output[1] = (byte) (R0 >> 8);
-               output[2] = (byte) R1;
-               output[3] = (byte) (R1 >> 8);
-               output[4] = (byte) R2;
-               output[5] = (byte) (R2 >> 8);
-               output[6] = (byte) R3;
-               output[7] = (byte) (R3 >> 8);
+       
+               static private byte[] pitable = {
+                       0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 
+                       0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
+                       0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, 
+                       0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
+                       0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, 
+                       0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
+                       0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 
+                       0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
+                       0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, 
+                       0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
+                       0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, 
+                       0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
+                       0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 
+                       0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
+                       0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, 
+                       0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
+                       0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, 
+                       0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
+                       0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 
+                       0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
+                       0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, 
+                       0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
+                       0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, 
+                       0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
+                       0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 
+                       0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
+                       0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, 
+                       0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
+                       0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, 
+                       0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
+                       0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 
+                       0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad 
+               };
        }
-
-       static private byte[] pitable = {
-               0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 
-               0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
-               0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, 
-               0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
-               0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, 
-               0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
-               0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 
-               0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
-               0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, 
-               0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
-               0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, 
-               0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
-               0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 
-               0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
-               0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, 
-               0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
-               0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, 
-               0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
-               0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 
-               0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
-               0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, 
-               0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
-               0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, 
-               0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
-               0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 
-               0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
-               0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, 
-               0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
-               0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, 
-               0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
-               0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 
-               0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad 
-       };
-}
-
 }
index 0efb8ce46863ac220e265f2551e363a95b0f590e..e6fa8200900bbe59f739bbf313fc070958b16d1d 100644 (file)
 using System;
 using System.IO;
 
-namespace System.Security.Cryptography {
-
-public sealed class RSACryptoServiceProvider : RSA {
-
-       private CspParameters cspParams;
-
-       private bool privateKeyExportable = true; 
-       private bool keypairGenerated = false;
-       private bool persistKey = false;
-       private bool m_disposed = false;
-
-       private BigInteger d;
-       private BigInteger p;
-       private BigInteger q;
-       private BigInteger dp;
-       private BigInteger dq;
-       private BigInteger qInv;
-       private BigInteger n;           // modulus
-       private BigInteger e;
-
-       public RSACryptoServiceProvider ()
-       {
-               // Here it's not clear if we need to generate a keypair
-               // (note: MS implementation generates a keypair in this case).
-               // However we:
-               // (a) often use this constructor to import an existing keypair.
-               // (b) take a LOT of time to generate the RSA keypair
-               // So we'll generate the keypair only when (and if) it's being
-               // used (or exported). This should save us a lot of time (at 
-               // least in the unit tests).
-               Common (null);
-       }
+using Mono.Math;
+using Mono.Security.Cryptography;
 
-       public RSACryptoServiceProvider (CspParameters parameters) 
-       {
-               Common (parameters);
-               // no keypair generation done at this stage
-       }
-
-       public RSACryptoServiceProvider (int dwKeySize) 
-       {
-               // Here it's clear that we need to generate a new keypair
-               Common (null);
-               GenerateKeyPair (dwKeySize);
-       }
-
-       // FIXME: We currently dont link with MS CAPI. Anyway this makes
-       // only sense in Windows - what do we do elsewhere ?
-       public RSACryptoServiceProvider (int dwKeySize, CspParameters parameters) 
-       {
-               Common (parameters);
-               GenerateKeyPair (dwKeySize);
-       }
+namespace System.Security.Cryptography {
 
-       [MonoTODO("Persistance")]
-       // FIXME: We currently dont link with MS CAPI. Anyway this makes
-       // only sense in Windows - what do we do elsewhere ?
-       private void Common (CspParameters p) 
-       {
-               cspParams = new CspParameters ();
-               if (p == null) {
-                       // TODO: set default values (for keypair persistance)
+       public sealed class RSACryptoServiceProvider : RSA {
+       
+               private CspParameters cspParams;
+       
+               private bool privateKeyExportable = true; 
+               private bool keypairGenerated = false;
+               private bool persistKey = false;
+               private bool m_disposed = false;
+       
+               private BigInteger d;
+               private BigInteger p;
+               private BigInteger q;
+               private BigInteger dp;
+               private BigInteger dq;
+               private BigInteger qInv;
+               private BigInteger n;           // modulus
+               private BigInteger e;
+       
+               public RSACryptoServiceProvider ()
+               {
+                       // Here it's not clear if we need to generate a keypair
+                       // (note: MS implementation generates a keypair in this case).
+                       // However we:
+                       // (a) often use this constructor to import an existing keypair.
+                       // (b) take a LOT of time to generate the RSA keypair
+                       // So we'll generate the keypair only when (and if) it's being
+                       // used (or exported). This should save us a lot of time (at 
+                       // least in the unit tests).
+                       Common (null);
                }
-               else {
-                       cspParams = p;
-                       // FIXME: We'll need this to support some kind of persistance
-                       throw new NotSupportedException ("CspParameters not supported");
+       
+               public RSACryptoServiceProvider (CspParameters parameters) 
+               {
+                       Common (parameters);
+                       // no keypair generation done at this stage
                }
-               // Microsoft RSA CSP can do between 384 and 16384 bits keypair
-               // we limit ourselve to 2048 because (a) BigInteger limits and (b) it's so SLOW
-               LegalKeySizesValue = new KeySizes [1];
-               LegalKeySizesValue [0] = new KeySizes (384, 2048, 8);
-       }
-
-       private void GenerateKeyPair (int dwKeySize) 
-       {
-               // will throw an exception is key size isn't supported
-               base.KeySize = dwKeySize;
-
-               // p and q values should have a length of half the strength in bits
-               int pbitlength = ((dwKeySize + 1) >> 1);
-               int qbitlength = (dwKeySize - pbitlength);
-               e = new BigInteger (17); // fixed
-
-               // generate p, prime and (p-1) relatively prime to e
-               for (;;) {
-                       p = BigInteger.genPseudoPrime (pbitlength, 80);
-                       if (e.gcd (p - 1) == 1)
-                               break;
+       
+               public RSACryptoServiceProvider (int dwKeySize) 
+               {
+                       // Here it's clear that we need to generate a new keypair
+                       Common (null);
+                       GenerateKeyPair (dwKeySize);
                }
-               // generate a modulus of the required length
-               for (;;) {
-                       // generate q, prime and (q-1) relatively prime to e,
-                       // and not equal to p
+       
+               // FIXME: We currently dont link with MS CAPI. Anyway this makes
+               // only sense in Windows - what do we do elsewhere ?
+               public RSACryptoServiceProvider (int dwKeySize, CspParameters parameters) 
+               {
+                       Common (parameters);
+                       GenerateKeyPair (dwKeySize);
+               }
+       
+               [MonoTODO("Persistance")]
+               // FIXME: We currently dont link with MS CAPI. Anyway this makes
+               // only sense in Windows - what do we do elsewhere ?
+               private void Common (CspParameters p) 
+               {
+                       cspParams = new CspParameters ();
+                       if (p == null) {
+                               // TODO: set default values (for keypair persistance)
+                       }
+                       else {
+                               cspParams = p;
+                               // FIXME: We'll need this to support some kind of persistance
+                               throw new NotSupportedException ("CspParameters not supported");
+                       }
+                       // Microsoft RSA CSP can do between 384 and 16384 bits keypair
+                       // we limit ourselve to 2048 because (a) BigInteger limits and (b) it's so SLOW
+                       LegalKeySizesValue = new KeySizes [1];
+                       LegalKeySizesValue [0] = new KeySizes (384, 2048, 8);
+               }
+       
+               private void GenerateKeyPair (int dwKeySize) 
+               {
+                       // will throw an exception is key size isn't supported
+                       base.KeySize = dwKeySize;
+       
+                       // p and q values should have a length of half the strength in bits
+                       int pbitlength = ((dwKeySize + 1) >> 1);
+                       int qbitlength = (dwKeySize - pbitlength);
+                       e = new BigInteger (17); // fixed
+       
+                       // generate p, prime and (p-1) relatively prime to e
                        for (;;) {
-                               q = BigInteger.genPseudoPrime (qbitlength, 80);
-                               if ((e.gcd (q - 1) == 1) && (p != q)) 
+                               p = BigInteger.genPseudoPrime (pbitlength, 80);
+                               if (e.gcd (p - 1) == 1)
                                        break;
                        }
-
-                       // calculate the modulus
-                       n = p * q;
-                       if (n.bitCount () == dwKeySize)
-                               break;
-
-                       // if we get here our primes aren't big enough, make the largest
-                       // of the two p and try again
-                       p = p.max (q);
+                       // generate a modulus of the required length
+                       for (;;) {
+                               // generate q, prime and (q-1) relatively prime to e,
+                               // and not equal to p
+                               for (;;) {
+                                       q = BigInteger.genPseudoPrime (qbitlength, 80);
+                                       if ((e.gcd (q - 1) == 1) && (p != q)) 
+                                               break;
+                               }
+       
+                               // calculate the modulus
+                               n = p * q;
+                               if (n.bitCount () == dwKeySize)
+                                       break;
+       
+                               // if we get here our primes aren't big enough, make the largest
+                               // of the two p and try again
+                               p = p.max (q);
+                       }
+       
+                       BigInteger pSub1 = (p - 1);
+                       BigInteger qSub1 = (q - 1);
+                       BigInteger phi = pSub1 * qSub1;
+       
+                       // calculate the private exponent
+                       d = e.modInverse (phi);
+       
+                       // calculate the CRT factors
+                       dp = d % pSub1;
+                       dq = d % qSub1;
+                       qInv = q.modInverse (p);
+       
+                       keypairGenerated = true;
                }
-
-               BigInteger pSub1 = (p - 1);
-               BigInteger qSub1 = (q - 1);
-               BigInteger phi = pSub1 * qSub1;
-
-               // calculate the private exponent
-               d = e.modInverse (phi);
-
-               // calculate the CRT factors
-               dp = d % pSub1;
-               dq = d % qSub1;
-               qInv = q.modInverse (p);
-
-               keypairGenerated = true;
-       }
-
-       // Zeroize private key
-       ~RSACryptoServiceProvider() 
-       {
-               Dispose (false);
-       }
-
-       public override string KeyExchangeAlgorithm {
-               get { return "RSA-PKCS1-KeyEx"; }
-       }
-
-       public override int KeySize {
-               get { return n.bitCount(); }
-       }
-
-       [MonoTODO("Persistance")]
-       public bool PersistKeyInCsp {
-               get { return false;  }
-               set { throw new NotSupportedException (); }
-       }
-
-       public override string SignatureAlgorithm {
-               get { return "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; }
-       }
-
-       public byte[] Decrypt (byte[] rgb, bool fOAEP) 
-       {
-               // choose between OAEP or PKCS#1 v.1.5 padding
-               if (fOAEP) {
-                       SHA1 sha1 = SHA1.Create ();
-                       return PKCS1.Decrypt_OAEP (this, sha1, null);
+       
+               // Zeroize private key
+               ~RSACryptoServiceProvider() 
+               {
+                       Dispose (false);
                }
-               else {
-                       return PKCS1.Decrypt_v15 (this, rgb);
+       
+               public override string KeyExchangeAlgorithm {
+                       get { return "RSA-PKCS1-KeyEx"; }
                }
-       }
-
-       // NOTE: Unlike MS we need this method
-       // LAMESPEC: Not available from MS .NET framework but MS don't tell
-       // why! DON'T USE IT UNLESS YOU KNOW WHAT YOU ARE DOING!!! You should
-       // only encrypt/decrypt session (secret) key using asymmetric keys. 
-       // Using this method to decrypt data IS dangerous (and very slow).
-       public override byte[] DecryptValue (byte[] rgb) 
-       {
-               // it would be stupid to decrypt data with a newly
-               // generated keypair - so we return false
-               if (!keypairGenerated)
-                       return null;
-
-               BigInteger input = new BigInteger (rgb);
-               BigInteger output = input.modPow (d, n);
-               return output.getBytes ();
-       }
-
-       public byte[] Encrypt (byte[] rgb, bool fOAEP) 
-       {
-               RandomNumberGenerator rng = RandomNumberGenerator.Create ();
-               // choose between OAEP or PKCS#1 v.1.5 padding
-               if (fOAEP) {
-                       SHA1 sha1 = SHA1.Create ();
-                       return PKCS1.Encrypt_OAEP (this, sha1, rng, rgb);
+       
+               public override int KeySize {
+                       get { return n.bitCount(); }
                }
-               else {
-                       return PKCS1.Encrypt_v15 (this, rng, rgb) ;
+       
+               [MonoTODO("Persistance")]
+               public bool PersistKeyInCsp {
+                       get { return false;  }
+                       set { throw new NotSupportedException (); }
                }
-       }
-
-       // NOTE: Unlike MS we need this method
-       // LAMESPEC: Not available from MS .NET framework but MS don't tell
-       // why! DON'T USE IT UNLESS YOU KNOW WHAT YOU ARE DOING!!! You should
-       // only encrypt/decrypt session (secret) key using asymmetric keys. 
-       // Using this method to encrypt data IS dangerous (and very slow).
-       public override byte[] EncryptValue (byte[] rgb) 
-       {
-               if (!keypairGenerated)
-                       GenerateKeyPair (1024);
-
-               // TODO: With CRT
-               // without CRT
-               BigInteger input = new BigInteger (rgb);
-               BigInteger output = input.modPow (e, n);
-               return output.getBytes ();
-       }
-
-       public override RSAParameters ExportParameters (bool includePrivateParameters) 
-       {
-               if ((includePrivateParameters) && (!privateKeyExportable))
-                       throw new CryptographicException ("cannot export private key");
-               if (!keypairGenerated)
-                       GenerateKeyPair (1024);
-
-               RSAParameters param = new RSAParameters();
-               param.Exponent = e.getBytes ();
-               param.Modulus = n.getBytes ();
-               if (includePrivateParameters) {
-                       param.D = d.getBytes ();
-                       param.DP = dp.getBytes ();
-                       param.DQ = dq.getBytes ();
-                       param.InverseQ = qInv.getBytes ();
-                       param.P = p.getBytes ();
-                       param.Q = q.getBytes ();
+       
+               public override string SignatureAlgorithm {
+                       get { return "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; }
                }
-               return param;
-       }
-
-       public override void ImportParameters (RSAParameters parameters) 
-       {
-               // if missing "mandatory" parameters
-               if ((parameters.Exponent == null) || (parameters.Modulus == null))
-                       throw new CryptographicException ();
-
-               e = new BigInteger (parameters.Exponent);
-               n = new BigInteger (parameters.Modulus);
-               // only if the private key is present
-               if (parameters.D != null)
-                       d = new BigInteger (parameters.D);
-               if (parameters.DP != null)
-                       dp = new BigInteger (parameters.DP);
-               if (parameters.DQ != null)
-                       dq = new BigInteger (parameters.DQ);
-               if (parameters.InverseQ != null)
-                       qInv = new BigInteger (parameters.InverseQ);
-               if (parameters.P != null)
-                       p = new BigInteger (parameters.P);
-               if (parameters.Q != null)
-                       q = new BigInteger (parameters.Q);
-               
-               // we now have a keypair
-               keypairGenerated = true;
-       }
-
-       private HashAlgorithm GetHash (object halg) 
-       {
-               if (halg == null)
-                       throw new ArgumentNullException ();
-
-               HashAlgorithm hash = null;
-               if (halg is String)
-                       hash = HashAlgorithm.Create ((String)halg);
-               else if (halg is HashAlgorithm)
-                       hash = (HashAlgorithm) halg;
-               else if (halg is Type)
-                       hash = (HashAlgorithm) Activator.CreateInstance ((Type)halg);
-               else
-                       throw new ArgumentException ();
-
-               return hash;
-       }
-
-       public byte[] SignData (byte[] buffer, object halg) 
-       {
-               return SignData (buffer, 0, buffer.Length, halg);
-       }
-
-       public byte[] SignData (Stream inputStream, object halg) 
-       {
-               HashAlgorithm hash = GetHash (halg);
-               byte[] toBeSigned = hash.ComputeHash (inputStream);
-
-               string oid = CryptoConfig.MapNameToOID (hash.ToString ());
-               return SignHash (toBeSigned, oid);
-       }
-
-       public byte[] SignData (byte[] buffer, int offset, int count, object halg) 
-       {
-               HashAlgorithm hash = GetHash (halg);
-               byte[] toBeSigned = hash.ComputeHash (buffer, offset, count);
-               string oid = CryptoConfig.MapNameToOID (hash.ToString ());
-               return SignHash (toBeSigned, oid);
-       }
-
-       private void ValidateHash (string oid, int length) 
-       {
-               if (oid == "1.3.14.3.2.26") {
-                       if (length != 20)
-                               throw new CryptographicException ("wrong hash size for SHA1");
+       
+               public byte[] Decrypt (byte[] rgb, bool fOAEP) 
+               {
+                       // choose between OAEP or PKCS#1 v.1.5 padding
+                       if (fOAEP) {
+                               SHA1 sha1 = SHA1.Create ();
+                               return PKCS1.Decrypt_OAEP (this, sha1, null);
+                       }
+                       else {
+                               return PKCS1.Decrypt_v15 (this, rgb);
+                       }
                }
-               else if (oid == "1.2.840.113549.2.5") {
-                       if (length != 16)
-                               throw new CryptographicException ("wrong hash size for MD5");
+       
+               // NOTE: Unlike MS we need this method
+               // LAMESPEC: Not available from MS .NET framework but MS don't tell
+               // why! DON'T USE IT UNLESS YOU KNOW WHAT YOU ARE DOING!!! You should
+               // only encrypt/decrypt session (secret) key using asymmetric keys. 
+               // Using this method to decrypt data IS dangerous (and very slow).
+               public override byte[] DecryptValue (byte[] rgb) 
+               {
+                       // it would be stupid to decrypt data with a newly
+                       // generated keypair - so we return false
+                       if (!keypairGenerated)
+                               return null;
+       
+                       BigInteger input = new BigInteger (rgb);
+                       BigInteger output = input.modPow (d, n);
+                       return output.getBytes ();
                }
-               else
-                       throw new NotSupportedException (oid + " is an unsupported hash algorithm for RSA signing");
-       }
-
-       public byte[] SignHash (byte[] rgbHash, string str) 
-       {
-               if (rgbHash == null)
-                       throw new ArgumentNullException ();
-
-               if (!keypairGenerated)
-                       GenerateKeyPair (1024);
-
-               ValidateHash (str, rgbHash.Length);
-
-               return PKCS1.Sign_v15 (this, str, rgbHash);
-       }
-
-       public bool VerifyData (byte[] buffer, object halg, byte[] signature) 
-       {
-               HashAlgorithm hash = GetHash (halg);
-               byte[] toBeVerified = hash.ComputeHash (buffer);
-               string oid = CryptoConfig.MapNameToOID (hash.ToString ());
-               return VerifyHash (toBeVerified, oid, signature);
-       }
-
-       public bool VerifyHash (byte[] rgbHash, string str, byte[] rgbSignature) 
-       {
-               if ((rgbHash == null) || (rgbSignature == null))
-                       throw new ArgumentNullException ();
-
-               // it would be stupid to verify a signature with a newly
-               // generated keypair - so we return false
-               if (!keypairGenerated)
-                       return false;
-
-               ValidateHash (str, rgbHash.Length);
-
-               return PKCS1.Verify_v15 (this, str, rgbHash, rgbSignature);
-       }
-
-       [MonoTODO()]
-       protected override void Dispose (bool disposing) 
-       {
-               if (!m_disposed) {
-                       // TODO: always zeroize private key
-                       if(disposing) {
-                               // TODO: Dispose managed resources
+       
+               public byte[] Encrypt (byte[] rgb, bool fOAEP) 
+               {
+                       RandomNumberGenerator rng = RandomNumberGenerator.Create ();
+                       // choose between OAEP or PKCS#1 v.1.5 padding
+                       if (fOAEP) {
+                               SHA1 sha1 = SHA1.Create ();
+                               return PKCS1.Encrypt_OAEP (this, sha1, rng, rgb);
+                       }
+                       else {
+                               return PKCS1.Encrypt_v15 (this, rng, rgb) ;
+                       }
+               }
+       
+               // NOTE: Unlike MS we need this method
+               // LAMESPEC: Not available from MS .NET framework but MS don't tell
+               // why! DON'T USE IT UNLESS YOU KNOW WHAT YOU ARE DOING!!! You should
+               // only encrypt/decrypt session (secret) key using asymmetric keys. 
+               // Using this method to encrypt data IS dangerous (and very slow).
+               public override byte[] EncryptValue (byte[] rgb) 
+               {
+                       if (!keypairGenerated)
+                               GenerateKeyPair (1024);
+       
+                       // TODO: With CRT
+                       // without CRT
+                       BigInteger input = new BigInteger (rgb);
+                       BigInteger output = input.modPow (e, n);
+                       return output.getBytes ();
+               }
+       
+               public override RSAParameters ExportParameters (bool includePrivateParameters) 
+               {
+                       if ((includePrivateParameters) && (!privateKeyExportable))
+                               throw new CryptographicException ("cannot export private key");
+                       if (!keypairGenerated)
+                               GenerateKeyPair (1024);
+       
+                       RSAParameters param = new RSAParameters();
+                       param.Exponent = e.getBytes ();
+                       param.Modulus = n.getBytes ();
+                       if (includePrivateParameters) {
+                               param.D = d.getBytes ();
+                               param.DP = dp.getBytes ();
+                               param.DQ = dq.getBytes ();
+                               param.InverseQ = qInv.getBytes ();
+                               param.P = p.getBytes ();
+                               param.Q = q.getBytes ();
+                       }
+                       return param;
+               }
+       
+               public override void ImportParameters (RSAParameters parameters) 
+               {
+                       // if missing "mandatory" parameters
+                       if ((parameters.Exponent == null) || (parameters.Modulus == null))
+                               throw new CryptographicException ();
+       
+                       e = new BigInteger (parameters.Exponent);
+                       n = new BigInteger (parameters.Modulus);
+                       // only if the private key is present
+                       if (parameters.D != null)
+                               d = new BigInteger (parameters.D);
+                       if (parameters.DP != null)
+                               dp = new BigInteger (parameters.DP);
+                       if (parameters.DQ != null)
+                               dq = new BigInteger (parameters.DQ);
+                       if (parameters.InverseQ != null)
+                               qInv = new BigInteger (parameters.InverseQ);
+                       if (parameters.P != null)
+                               p = new BigInteger (parameters.P);
+                       if (parameters.Q != null)
+                               q = new BigInteger (parameters.Q);
+                       
+                       // we now have a keypair
+                       keypairGenerated = true;
+               }
+       
+               private HashAlgorithm GetHash (object halg) 
+               {
+                       if (halg == null)
+                               throw new ArgumentNullException ();
+       
+                       HashAlgorithm hash = null;
+                       if (halg is String)
+                               hash = HashAlgorithm.Create ((String)halg);
+                       else if (halg is HashAlgorithm)
+                               hash = (HashAlgorithm) halg;
+                       else if (halg is Type)
+                               hash = (HashAlgorithm) Activator.CreateInstance ((Type)halg);
+                       else
+                               throw new ArgumentException ();
+       
+                       return hash;
+               }
+       
+               public byte[] SignData (byte[] buffer, object halg) 
+               {
+                       return SignData (buffer, 0, buffer.Length, halg);
+               }
+       
+               public byte[] SignData (Stream inputStream, object halg) 
+               {
+                       HashAlgorithm hash = GetHash (halg);
+                       byte[] toBeSigned = hash.ComputeHash (inputStream);
+       
+                       string oid = CryptoConfig.MapNameToOID (hash.ToString ());
+                       return SignHash (toBeSigned, oid);
+               }
+       
+               public byte[] SignData (byte[] buffer, int offset, int count, object halg) 
+               {
+                       HashAlgorithm hash = GetHash (halg);
+                       byte[] toBeSigned = hash.ComputeHash (buffer, offset, count);
+                       string oid = CryptoConfig.MapNameToOID (hash.ToString ());
+                       return SignHash (toBeSigned, oid);
+               }
+       
+               private void ValidateHash (string oid, int length) 
+               {
+                       if (oid == "1.3.14.3.2.26") {
+                               if (length != 20)
+                                       throw new CryptographicException ("wrong hash size for SHA1");
+                       }
+                       else if (oid == "1.2.840.113549.2.5") {
+                               if (length != 16)
+                                       throw new CryptographicException ("wrong hash size for MD5");
                        }
-         
-                       // TODO: Dispose unmanaged resources
+                       else
+                               throw new NotSupportedException (oid + " is an unsupported hash algorithm for RSA signing");
+               }
+       
+               public byte[] SignHash (byte[] rgbHash, string str) 
+               {
+                       if (rgbHash == null)
+                               throw new ArgumentNullException ();
+       
+                       if (!keypairGenerated)
+                               GenerateKeyPair (1024);
+       
+                       ValidateHash (str, rgbHash.Length);
+       
+                       return PKCS1.Sign_v15 (this, str, rgbHash);
+               }
+       
+               public bool VerifyData (byte[] buffer, object halg, byte[] signature) 
+               {
+                       HashAlgorithm hash = GetHash (halg);
+                       byte[] toBeVerified = hash.ComputeHash (buffer);
+                       string oid = CryptoConfig.MapNameToOID (hash.ToString ());
+                       return VerifyHash (toBeVerified, oid, signature);
+               }
+       
+               public bool VerifyHash (byte[] rgbHash, string str, byte[] rgbSignature) 
+               {
+                       if ((rgbHash == null) || (rgbSignature == null))
+                               throw new ArgumentNullException ();
+       
+                       // it would be stupid to verify a signature with a newly
+                       // generated keypair - so we return false
+                       if (!keypairGenerated)
+                               return false;
+       
+                       ValidateHash (str, rgbHash.Length);
+       
+                       return PKCS1.Verify_v15 (this, str, rgbHash, rgbSignature);
+               }
+       
+               [MonoTODO()]
+               protected override void Dispose (bool disposing) 
+               {
+                       if (!m_disposed) {
+                               // TODO: always zeroize private key
+                               if(disposing) {
+                                       // TODO: Dispose managed resources
+                               }
+                
+                               // TODO: Dispose unmanaged resources
+                       }
+                       // call base class 
+                       // no need as they all are abstract before us
+                       m_disposed = true;
                }
-               // call base class 
-               // no need as they all are abstract before us
-               m_disposed = true;
        }
 }
-
-}
index 35932973b30516aeb7717f4af011b5ec66337737..beb1407a2987b7b74dceb5db631537bccd317d0a 100644 (file)
@@ -8,46 +8,46 @@
 //
 
 using System;
+using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography { 
 
-public class RSAOAEPKeyExchangeDeformatter : AsymmetricKeyExchangeDeformatter {
-
-       private RSA rsa;
-       private string param;
-
-       public RSAOAEPKeyExchangeDeformatter ()
-       {
-               rsa = null;
-       }
-
-       public RSAOAEPKeyExchangeDeformatter (AsymmetricAlgorithm key) 
-       {
-               SetKey (key);
-       }
-
-       public override string Parameters {
-               get { return param; }
-               set { param = value; }
-       }
-
-       public override byte[] DecryptKeyExchange (byte[] rgbData) 
-       {
-               if (rsa == null)
-                       throw new CryptographicException ();
-
-               SHA1 sha1 = SHA1.Create ();
-               return PKCS1.Decrypt_OAEP (rsa, sha1, rgbData);
-       }
-
-       public override void SetKey (AsymmetricAlgorithm key) 
-       {
-               if (key is RSA) {
-                       rsa = (RSA)key;
+       public class RSAOAEPKeyExchangeDeformatter : AsymmetricKeyExchangeDeformatter {
+       
+               private RSA rsa;
+               private string param;
+       
+               public RSAOAEPKeyExchangeDeformatter ()
+               {
+                       rsa = null;
+               }
+       
+               public RSAOAEPKeyExchangeDeformatter (AsymmetricAlgorithm key) 
+               {
+                       SetKey (key);
+               }
+       
+               public override string Parameters {
+                       get { return param; }
+                       set { param = value; }
+               }
+       
+               public override byte[] DecryptKeyExchange (byte[] rgbData) 
+               {
+                       if (rsa == null)
+                               throw new CryptographicException ();
+       
+                       SHA1 sha1 = SHA1.Create ();
+                       return PKCS1.Decrypt_OAEP (rsa, sha1, rgbData);
+               }
+       
+               public override void SetKey (AsymmetricAlgorithm key) 
+               {
+                       if (key is RSA) {
+                               rsa = (RSA)key;
+                       }
+                       else
+                               throw new CryptographicException ();
                }
-               else
-                       throw new CryptographicException ();
        }
 }
-
-}
index b7ebd2a57fabd59e466113b7fb404dc551d4de50..4ea3ff475ddb12de53dc7483308067129a37cffd 100644 (file)
@@ -8,64 +8,64 @@
 //
 
 using System;
+using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography { 
 
-public class RSAOAEPKeyExchangeFormatter : AsymmetricKeyExchangeFormatter {
-
-       private RSA rsa;
-       private RandomNumberGenerator random;
-
-       public RSAOAEPKeyExchangeFormatter () 
-       {
-               rsa = null;
-       }
-
-       public RSAOAEPKeyExchangeFormatter (AsymmetricAlgorithm key) 
-       {
-               SetKey (key);
-       }
-
-       public byte[] Parameter {
-               get { return null; }
-               set { ; }
-       }
-
-       public override string Parameters {
-               get { return null; }
-       }
-
-       public RandomNumberGenerator Rng {
-               get { return random; }
-               set { random = value; }
-       }
-
-       public override byte[] CreateKeyExchange (byte[] rgbData) 
-       {
-               if (rsa == null)
-                       throw new CryptographicException ();
-               if (random == null)
-                       random = RandomNumberGenerator.Create ();  // create default
-
-               SHA1 sha1 = SHA1.Create ();
-               return PKCS1.Encrypt_OAEP (rsa, sha1, random, rgbData);
-       }
-
-       public override byte[] CreateKeyExchange (byte[] rgbData, Type symAlgType) 
-       {
-               // documentation says that symAlgType is not used !?!
-               // FIXME: must be the same as previous method ?
-               return CreateKeyExchange (rgbData);
-       }
-
-       public override void SetKey (AsymmetricAlgorithm key) 
-       {
-               if (key is RSA) {
-                       rsa = (RSA) key;
+       public class RSAOAEPKeyExchangeFormatter : AsymmetricKeyExchangeFormatter {
+       
+               private RSA rsa;
+               private RandomNumberGenerator random;
+       
+               public RSAOAEPKeyExchangeFormatter () 
+               {
+                       rsa = null;
+               }
+       
+               public RSAOAEPKeyExchangeFormatter (AsymmetricAlgorithm key) 
+               {
+                       SetKey (key);
+               }
+       
+               public byte[] Parameter {
+                       get { return null; }
+                       set { ; }
+               }
+       
+               public override string Parameters {
+                       get { return null; }
+               }
+       
+               public RandomNumberGenerator Rng {
+                       get { return random; }
+                       set { random = value; }
+               }
+       
+               public override byte[] CreateKeyExchange (byte[] rgbData) 
+               {
+                       if (rsa == null)
+                               throw new CryptographicException ();
+                       if (random == null)
+                               random = RandomNumberGenerator.Create ();  // create default
+       
+                       SHA1 sha1 = SHA1.Create ();
+                       return PKCS1.Encrypt_OAEP (rsa, sha1, random, rgbData);
+               }
+       
+               public override byte[] CreateKeyExchange (byte[] rgbData, Type symAlgType) 
+               {
+                       // documentation says that symAlgType is not used !?!
+                       // FIXME: must be the same as previous method ?
+                       return CreateKeyExchange (rgbData);
+               }
+       
+               public override void SetKey (AsymmetricAlgorithm key) 
+               {
+                       if (key is RSA) {
+                               rsa = (RSA) key;
+                       }
+                       else
+                               throw new CryptographicException ();
                }
-               else
-                       throw new CryptographicException ();
        }
 }
-
-}
index d9ae1ccbeadc95615663a0115cbb313f3dd589ee..9fcbf2482222b66b2e04fc727238153992e93afa 100644 (file)
@@ -8,50 +8,50 @@
 //
 
 using System;
+using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography { 
 
-public class RSAPKCS1KeyExchangeDeformatter : AsymmetricKeyExchangeDeformatter {
-
-       private RSA rsa;
-       private string param;
-       private RandomNumberGenerator random;
-
-       public RSAPKCS1KeyExchangeDeformatter () 
-       {
-               rsa = null;
-       }
-
-       public RSAPKCS1KeyExchangeDeformatter (AsymmetricAlgorithm key) 
-       {
-               SetKey (key);
-       }
-
-       public override string Parameters {
-               get { return param; }
-               set { param = value; }
-       }
-
-       public RandomNumberGenerator RNG {
-               get { return random; }
-               set { random = value; }
-       }
-
-       public override byte[] DecryptKeyExchange (byte[] rgbData) 
-       {
-               if (rsa == null)
-                       throw new CryptographicException ();
-               return PKCS1.Decrypt_v15 (rsa, rgbData);
-       }
-
-       public override void SetKey (AsymmetricAlgorithm key) 
-       {
-               if (key is RSA) {
-                       rsa = (RSA)key;
+       public class RSAPKCS1KeyExchangeDeformatter : AsymmetricKeyExchangeDeformatter {
+       
+               private RSA rsa;
+               private string param;
+               private RandomNumberGenerator random;
+       
+               public RSAPKCS1KeyExchangeDeformatter () 
+               {
+                       rsa = null;
+               }
+       
+               public RSAPKCS1KeyExchangeDeformatter (AsymmetricAlgorithm key) 
+               {
+                       SetKey (key);
+               }
+       
+               public override string Parameters {
+                       get { return param; }
+                       set { param = value; }
+               }
+       
+               public RandomNumberGenerator RNG {
+                       get { return random; }
+                       set { random = value; }
+               }
+       
+               public override byte[] DecryptKeyExchange (byte[] rgbData) 
+               {
+                       if (rsa == null)
+                               throw new CryptographicException ();
+                       return PKCS1.Decrypt_v15 (rsa, rgbData);
+               }
+       
+               public override void SetKey (AsymmetricAlgorithm key) 
+               {
+                       if (key is RSA) {
+                               rsa = (RSA)key;
+                       }
+                       else
+                               throw new CryptographicException ();
                }
-               else
-                       throw new CryptographicException ();
        }
 }
-
-}
index c802c6dc6be003dce68559998958b01f928597ee..40f0c51fbf557de782297ec9f64e171b7251a635 100644 (file)
@@ -8,66 +8,64 @@
 //
 
 using System;
-using System.Security.Cryptography;
+using Mono.Security.Cryptography;
 
-namespace System.Security.Cryptography
-{
-
-// LAMESPEC: There seems no way to select a hash algorithm. The default 
-// algorithm, is SHA1 because the class use the PKCS1MaskGenerationMethod -
-// which default to SHA1.
-public class RSAPKCS1KeyExchangeFormatter: AsymmetricKeyExchangeFormatter
-{
-       private RSA rsa;
-       private RandomNumberGenerator random;
-
-       public RSAPKCS1KeyExchangeFormatter ()
-       {
-       }
-
-       public RSAPKCS1KeyExchangeFormatter (AsymmetricAlgorithm key)
-       {
-               SetKey (key);
-       }
-
-       public RandomNumberGenerator Rng 
-       {
-               get { return random; }
-               set { random = value; }
-       }
-
-       public override string Parameters 
-       {
-               get { return "<enc:KeyEncryptionMethod enc:Algorithm=\"http://www.microsoft.com/xml/security/algorithm/PKCS1-v1.5-KeyEx\" xmlns:enc=\"http://www.microsoft.com/xml/security/encryption/v1.0\" />"; }
-       }
-
-       public override byte[] CreateKeyExchange (byte[] rgbData)
+namespace System.Security.Cryptography {
+       
+       // LAMESPEC: There seems no way to select a hash algorithm. The default 
+       // algorithm, is SHA1 because the class use the PKCS1MaskGenerationMethod -
+       // which default to SHA1.
+       public class RSAPKCS1KeyExchangeFormatter: AsymmetricKeyExchangeFormatter
        {
-               if (rsa == null)
-                       throw new CryptographicException ();
-               if (random == null)
-                       random = RandomNumberGenerator.Create ();  // create default
-               return PKCS1.Encrypt_v15 (rsa, random, rgbData);
-       }
-
-       public override byte[] CreateKeyExchange (byte[] rgbData, Type symAlgType)
-       {
-               // documentation says that symAlgType is not used !?!
-               // FIXME: must be the same as previous method ?
-               return CreateKeyExchange (rgbData);
-       }
-
-       public override void SetKey (AsymmetricAlgorithm key)
-       {
-               if (key != null) {
-                       if (key is RSA) {
-                               rsa = (RSA)key;
+               private RSA rsa;
+               private RandomNumberGenerator random;
+       
+               public RSAPKCS1KeyExchangeFormatter ()
+               {
+               }
+       
+               public RSAPKCS1KeyExchangeFormatter (AsymmetricAlgorithm key)
+               {
+                       SetKey (key);
+               }
+       
+               public RandomNumberGenerator Rng 
+               {
+                       get { return random; }
+                       set { random = value; }
+               }
+       
+               public override string Parameters 
+               {
+                       get { return "<enc:KeyEncryptionMethod enc:Algorithm=\"http://www.microsoft.com/xml/security/algorithm/PKCS1-v1.5-KeyEx\" xmlns:enc=\"http://www.microsoft.com/xml/security/encryption/v1.0\" />"; }
+               }
+       
+               public override byte[] CreateKeyExchange (byte[] rgbData)
+               {
+                       if (rsa == null)
+                               throw new CryptographicException ();
+                       if (random == null)
+                               random = RandomNumberGenerator.Create ();  // create default
+                       return PKCS1.Encrypt_v15 (rsa, random, rgbData);
+               }
+       
+               public override byte[] CreateKeyExchange (byte[] rgbData, Type symAlgType)
+               {
+                       // documentation says that symAlgType is not used !?!
+                       // FIXME: must be the same as previous method ?
+                       return CreateKeyExchange (rgbData);
+               }
+       
+               public override void SetKey (AsymmetricAlgorithm key)
+               {
+                       if (key != null) {
+                               if (key is RSA) {
+                                       rsa = (RSA)key;
+                               }
+                               else
+                                       throw new InvalidCastException ();
                        }
-                       else
-                               throw new InvalidCastException ();
+                       // here null is accepted!
                }
-               // here null is accepted!
        }
 }
-
-}
index fddf293e58d55e4f9a59b3d1039ba88843c92032..3c985fd0cd98c884dfde0a24549b4e8d2461dad6 100644 (file)
@@ -8,48 +8,48 @@
 //
 
 using System;
+using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography { 
-
-public class RSAPKCS1SignatureDeformatter : AsymmetricSignatureDeformatter {
-
-       private RSA rsa;
-       private string hashName;
-
-       public RSAPKCS1SignatureDeformatter () 
-       {
-               rsa = null;
-       }
-
-       public RSAPKCS1SignatureDeformatter (AsymmetricAlgorithm key) 
-       {
-               SetKey (key);
-       }
-
-       public override void SetHashAlgorithm (string strName) 
-       {
-               if (strName == null)
-                       throw new ArgumentNullException ("strName");
-               hashName = strName;
+       
+       public class RSAPKCS1SignatureDeformatter : AsymmetricSignatureDeformatter {
+       
+               private RSA rsa;
+               private string hashName;
+       
+               public RSAPKCS1SignatureDeformatter () 
+               {
+                       rsa = null;
+               }
+       
+               public RSAPKCS1SignatureDeformatter (AsymmetricAlgorithm key) 
+               {
+                       SetKey (key);
+               }
+       
+               public override void SetHashAlgorithm (string strName) 
+               {
+                       if (strName == null)
+                               throw new ArgumentNullException ("strName");
+                       hashName = strName;
+               }
+       
+               public override void SetKey (AsymmetricAlgorithm key) 
+               {
+                       if (key != null)
+                               rsa = (RSA)key;
+                       // here null is accepted with an ArgumentNullException!
+               }
+       
+               public override bool VerifySignature (byte[] rgbHash, byte[] rgbSignature) 
+               {
+                       if ((rsa == null) || (hashName == null))
+                               throw new CryptographicUnexpectedOperationException ();
+                       if ((rgbHash == null) || (rgbSignature == null))
+                               throw new ArgumentNullException ();
+       
+                       string oid = CryptoConfig.MapNameToOID (hashName);
+                       return PKCS1.Verify_v15 (rsa, oid, rgbHash, rgbSignature);
+               }
        }
-
-       public override void SetKey (AsymmetricAlgorithm key) 
-       {
-               if (key != null)
-                       rsa = (RSA)key;
-               // here null is accepted with an ArgumentNullException!
-       }
-
-       public override bool VerifySignature (byte[] rgbHash, byte[] rgbSignature) 
-       {
-               if ((rsa == null) || (hashName == null))
-                       throw new CryptographicUnexpectedOperationException ();
-               if ((rgbHash == null) || (rgbSignature == null))
-                       throw new ArgumentNullException ();
-
-               string oid = CryptoConfig.MapNameToOID (hashName);
-               return PKCS1.Verify_v15 (rsa, oid, rgbHash, rgbSignature);
-       }
-}
-
 }
index 6ed64673fc947c3c1ea352ff41ddd4a2d3ef9f74..9f62f4b7faadba7e2e886120cd37fccd4f7f3d72 100644 (file)
@@ -8,51 +8,51 @@
 //
 
 using System;
+using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography { 
-
-public class RSAPKCS1SignatureFormatter : AsymmetricSignatureFormatter {
-
-       private RSA rsa;
-       private HashAlgorithm hash;
-
-       public RSAPKCS1SignatureFormatter () 
-       {
-               rsa = null;
-       }
-
-       public RSAPKCS1SignatureFormatter (AsymmetricAlgorithm key) 
-       {
-               SetKey (key);
-       }
-
-       public override byte[] CreateSignature (byte[] rgbHash) 
-       {
-               if ((rsa == null) || (hash == null))
-                       throw new CryptographicUnexpectedOperationException ();
-               if (rgbHash == null)
-                       throw new ArgumentNullException ();
-
-               string oid = CryptoConfig.MapNameToOID (hash.ToString ());
-               return PKCS1.Sign_v15 (rsa, oid, rgbHash);
-       }
-
-       public override void SetHashAlgorithm (string strName) 
-       {
-               hash = HashAlgorithm.Create (strName);
-       }
-
-       public override void SetKey (AsymmetricAlgorithm key) 
-       {
-               if (key != null) {
-                       if (key is RSA) {
-                               rsa = (RSA)key;
+       
+       public class RSAPKCS1SignatureFormatter : AsymmetricSignatureFormatter {
+       
+               private RSA rsa;
+               private HashAlgorithm hash;
+       
+               public RSAPKCS1SignatureFormatter () 
+               {
+                       rsa = null;
+               }
+       
+               public RSAPKCS1SignatureFormatter (AsymmetricAlgorithm key) 
+               {
+                       SetKey (key);
+               }
+       
+               public override byte[] CreateSignature (byte[] rgbHash) 
+               {
+                       if ((rsa == null) || (hash == null))
+                               throw new CryptographicUnexpectedOperationException ();
+                       if (rgbHash == null)
+                               throw new ArgumentNullException ();
+       
+                       string oid = CryptoConfig.MapNameToOID (hash.ToString ());
+                       return PKCS1.Sign_v15 (rsa, oid, rgbHash);
+               }
+       
+               public override void SetHashAlgorithm (string strName) 
+               {
+                       hash = HashAlgorithm.Create (strName);
+               }
+       
+               public override void SetKey (AsymmetricAlgorithm key) 
+               {
+                       if (key != null) {
+                               if (key is RSA) {
+                                       rsa = (RSA)key;
+                               }
+                               else
+                                       throw new InvalidCastException ();
                        }
-                       else
-                               throw new InvalidCastException ();
+                       // here null is accepted!
                }
-               // here null is accepted!
        }
 }
-
-}
index 73b5efeef6fc9d747eb9d480e13aaa1333350d36..c003bc139c9f7af4dccfc8123ca279b52dd60fa3 100644 (file)
@@ -10,6 +10,7 @@
 //
 
 using System;
+using Mono.Security.Cryptography;
 
 /// <summary>
 /// Rijndael is a symmetric block cipher supporting block and key sizes
@@ -17,506 +18,504 @@ using System;
 /// </summary>
 
 namespace System.Security.Cryptography {
-
-// References:
-// a.  FIPS PUB 197: Advanced Encryption Standard
-//     http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
-
-public sealed class RijndaelManaged : Rijndael {
-       
-       /// <summary>
-       /// RijndaelManaged constructor.
-       /// </summary>
-       public RijndaelManaged() {}
-       
-       /// <summary>
-       /// Generates a random IV for block feedback modes
-       /// </summary>
-       /// <remarks>
-       /// Method is inherited from SymmetricAlgorithm
-       /// </remarks>
-       public override void GenerateIV () 
-       {
-               IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
-       }
        
-       /// <summary>
-       /// Generates a random key for Rijndael.  Uses the current KeySize.
-       /// </summary>
-       /// <remarks>
-       /// Inherited method from base class SymmetricAlgorithm
-       /// </remarks>
-       public override void GenerateKey () 
-       {
-               KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
-       }
-       
-       /// <summary>
-       /// Creates a symmetric Rijndael decryptor object
-       /// </summary>
-       /// <remarks>
-       /// Inherited method from base class SymmetricAlgorithm
-       /// </remarks>
-       /// <param name='rgbKey'>Key for Rijndael</param>
-       /// <param name='rgbIV'>IV for chaining mode</param>
-       public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) 
-       {
-               Key = rgbKey;
-               IV = rgbIV;
-               return new RijndaelTransform (this, false, rgbKey, rgbIV);
-       }
+       // References:
+       // a.   FIPS PUB 197: Advanced Encryption Standard
+       //      http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
        
-       /// <summary>
-       /// Creates a symmetric Rijndael encryptor object
-       /// </summary>
-       /// <remarks>
-       /// Inherited method from base class SymmetricAlgorithm
-       /// </remarks>
-       /// <param name='rgbKey'>Key for Rijndael</param>
-       /// <param name='rgbIV'>IV for chaining mode</param>
-       public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) 
-       {
-               Key = rgbKey;
-               IV = rgbIV;
-               return new RijndaelTransform (this, true, rgbKey, rgbIV);
-       }
-}
-
-
-internal class RijndaelTransform : SymmetricTransform
-{
-       private byte[] key;
-       private byte[] expandedKey;
-
-       private int Nb;
-       private int Nk;
-       private int Nr;
-       private byte[] eshifts;
-       private byte[] dshifts;
-
-       private byte[] state;
-       private byte[] shifttemp;
-
-       private static byte[] e256shifts = { 1, 3, 4 };
-       private static byte[] d256shifts = { 7, 5, 4 };
-       private static byte[] e192shifts = { 1, 2, 3 };
-       private static byte[] d192shifts = { 5, 4, 3 };
-       private static byte[] e128shifts = { 1, 2, 3 };
-       private static byte[] d128shifts = { 3, 2, 1 };
-
-       private static Int32[] rcon = { 0, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, -2147483648, 452984832, 905969664, 1811939328, -671088640, -1426063360, 1291845632, -1711276032, 788529152, 1577058304, -1140850688, 1660944384, -973078528, -1761607680, 889192448, 1778384896, -738197504, -1291845632, 2097152000, -100663296, -285212672, -989855744, -1862270976 };
-
-       public RijndaelTransform (Rijndael algo, bool encryption, byte[] key, byte[] iv) : base (algo, encryption, iv)
-       {
-               int keySize = algo.KeySize;
-               if (keySize != 128 && keySize != 192 && keySize != 256) 
-                       throw new ArgumentException("Illegal key size");
-
-               int blockSize = algo.BlockSize;
-               if (blockSize != 128 && blockSize != 192 && blockSize != 256) 
-                       throw new ArgumentException("Illegal block size");
-
-               if ((key.Length << 3) != keySize) 
-                       throw new ArgumentException("Key size doesn't match key");
-
-               this.key = key;
-               this.Nb = (blockSize >> 5); // div 32
-               this.Nk = (keySize >> 5); // div 32
-               state = new byte [Nb << 2];
-               shifttemp = new byte [Nb << 2];
-
-               if (Nb == 8 || Nk == 8) {
-                       Nr = 14;
-               } else if (Nb == 6 || Nk == 6) {
-                       Nr = 12;
-               } else {
-                       Nr = 10;
-               }
-
-               switch (Nb) {
-                       case 8: // 256 bits
-                               eshifts = e256shifts;
-                               dshifts = d256shifts;
-                               break;
-                       case 6: // 192 bits
-                               eshifts = e192shifts;
-                               dshifts = d192shifts;
-                               break;
-                       case 4: // 128 bits
-                               eshifts = e128shifts;
-                               dshifts = d128shifts;
-                               break;
+       public sealed class RijndaelManaged : Rijndael {
+               
+               /// <summary>
+               /// RijndaelManaged constructor.
+               /// </summary>
+               public RijndaelManaged() {}
+               
+               /// <summary>
+               /// Generates a random IV for block feedback modes
+               /// </summary>
+               /// <remarks>
+               /// Method is inherited from SymmetricAlgorithm
+               /// </remarks>
+               public override void GenerateIV () 
+               {
+                       IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
                }
-
-               // Setup Expanded Key
-               int exKeySize = Nb * (Nr+1);
-               Int32[] exKey = new Int32[exKeySize];
-               int pos = 0;
-               for (int i=0; i < Nk; i++) {
-                       Int32 value = (key [pos++] << 24);
-                       value |= (key [pos++] << 16);
-                       value |= (key [pos++] << 8);
-                       value |= (key [pos++]);
-                       exKey [i] = value;
+               
+               /// <summary>
+               /// Generates a random key for Rijndael.  Uses the current KeySize.
+               /// </summary>
+               /// <remarks>
+               /// Inherited method from base class SymmetricAlgorithm
+               /// </remarks>
+               public override void GenerateKey () 
+               {
+                       KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
                }
-
-               for (int i = Nk; i < exKeySize; i++) {
-                       Int32 temp = exKey [i-1];
-                       if (i % Nk == 0) {
-                               Int32 rot = (Int32) ((temp << 8) | ((temp >> 24) & 0xff));
-                               temp = SubByte (rot) ^ rcon [i / Nk];
-                       } else if (Nk > 6 && (i % Nk) == 4) {
-                               temp = SubByte (temp);
-                       }
-                       exKey [i] = exKey [i-Nk] ^ temp;
+               
+               /// <summary>
+               /// Creates a symmetric Rijndael decryptor object
+               /// </summary>
+               /// <remarks>
+               /// Inherited method from base class SymmetricAlgorithm
+               /// </remarks>
+               /// <param name='rgbKey'>Key for Rijndael</param>
+               /// <param name='rgbIV'>IV for chaining mode</param>
+               public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) 
+               {
+                       Key = rgbKey;
+                       IV = rgbIV;
+                       return new RijndaelTransform (this, false, rgbKey, rgbIV);
                }
-
-               // convert key to byte array (better performance)
-               // TODO: Don't convert - expand key directly in byte array
-               expandedKey = new byte [exKey.Length << 2];
-               int k = 0;
-               for (int i=0; i < exKey.Length; i++) {
-                       expandedKey [k++] = (byte) (exKey[i] >> 24);
-                       expandedKey [k++] = (byte) ((exKey[i] >> 16) & 0xff);
-                       expandedKey [k++] = (byte) ((exKey[i] >> 8) & 0xff);
-                       expandedKey [k++] = (byte) (exKey[i] & 0xff);
+               
+               /// <summary>
+               /// Creates a symmetric Rijndael encryptor object
+               /// </summary>
+               /// <remarks>
+               /// Inherited method from base class SymmetricAlgorithm
+               /// </remarks>
+               /// <param name='rgbKey'>Key for Rijndael</param>
+               /// <param name='rgbIV'>IV for chaining mode</param>
+               public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) 
+               {
+                       Key = rgbKey;
+                       IV = rgbIV;
+                       return new RijndaelTransform (this, true, rgbKey, rgbIV);
                }
        }
-
-       // note: this method is guaranteed to be called with a valid blocksize
-       // for both input and output
-       protected override void ECB (byte[] input, byte[] output) 
+       
+       
+       internal class RijndaelTransform : SymmetricTransform
        {
-               int pos, ori;
-               for (pos = 0; pos < input.Length; pos++)
-                       state [pos] = input [pos];
-
-               if (encrypt) {
-                       // inline AddRoundKey (0, true);
-                       int roundoffset = 0;
-                       int p = 0;
-                       for (pos = 0; pos < state.Length; pos++)
-                               state [pos] ^= expandedKey [p++];
-
-                       for (int round = 1; round < Nr; round++) {
+               private byte[] key;
+               private byte[] expandedKey;
+       
+               private int Nb;
+               private int Nk;
+               private int Nr;
+               private byte[] eshifts;
+               private byte[] dshifts;
+       
+               private byte[] state;
+               private byte[] shifttemp;
+       
+               private static byte[] e256shifts = { 1, 3, 4 };
+               private static byte[] d256shifts = { 7, 5, 4 };
+               private static byte[] e192shifts = { 1, 2, 3 };
+               private static byte[] d192shifts = { 5, 4, 3 };
+               private static byte[] e128shifts = { 1, 2, 3 };
+               private static byte[] d128shifts = { 3, 2, 1 };
+       
+               private static Int32[] rcon = { 0, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, -2147483648, 452984832, 905969664, 1811939328, -671088640, -1426063360, 1291845632, -1711276032, 788529152, 1577058304, -1140850688, 1660944384, -973078528, -1761607680, 889192448, 1778384896, -738197504, -1291845632, 2097152000, -100663296, -285212672, -989855744, -1862270976 };
+       
+               public RijndaelTransform (Rijndael algo, bool encryption, byte[] key, byte[] iv) : base (algo, encryption, iv)
+               {
+                       int keySize = algo.KeySize;
+                       if (keySize != 128 && keySize != 192 && keySize != 256) 
+                               throw new ArgumentException("Illegal key size");
+       
+                       int blockSize = algo.BlockSize;
+                       if (blockSize != 128 && blockSize != 192 && blockSize != 256) 
+                               throw new ArgumentException("Illegal block size");
+       
+                       if ((key.Length << 3) != keySize) 
+                               throw new ArgumentException("Key size doesn't match key");
+       
+                       this.key = key;
+                       this.Nb = (blockSize >> 5); // div 32
+                       this.Nk = (keySize >> 5); // div 32
+                       state = new byte [Nb << 2];
+                       shifttemp = new byte [Nb << 2];
+       
+                       if (Nb == 8 || Nk == 8) {
+                               Nr = 14;
+                       } else if (Nb == 6 || Nk == 6) {
+                               Nr = 12;
+                       } else {
+                               Nr = 10;
+                       }
+       
+                       switch (Nb) {
+                               case 8: // 256 bits
+                                       eshifts = e256shifts;
+                                       dshifts = d256shifts;
+                                       break;
+                               case 6: // 192 bits
+                                       eshifts = e192shifts;
+                                       dshifts = d192shifts;
+                                       break;
+                               case 4: // 128 bits
+                                       eshifts = e128shifts;
+                                       dshifts = d128shifts;
+                                       break;
+                       }
+       
+                       // Setup Expanded Key
+                       int exKeySize = Nb * (Nr+1);
+                       Int32[] exKey = new Int32[exKeySize];
+                       int pos = 0;
+                       for (int i=0; i < Nk; i++) {
+                               Int32 value = (key [pos++] << 24);
+                               value |= (key [pos++] << 16);
+                               value |= (key [pos++] << 8);
+                               value |= (key [pos++]);
+                               exKey [i] = value;
+                       }
+       
+                       for (int i = Nk; i < exKeySize; i++) {
+                               Int32 temp = exKey [i-1];
+                               if (i % Nk == 0) {
+                                       Int32 rot = (Int32) ((temp << 8) | ((temp >> 24) & 0xff));
+                                       temp = SubByte (rot) ^ rcon [i / Nk];
+                               } else if (Nk > 6 && (i % Nk) == 4) {
+                                       temp = SubByte (temp);
+                               }
+                               exKey [i] = exKey [i-Nk] ^ temp;
+                       }
+       
+                       // convert key to byte array (better performance)
+                       // TODO: Don't convert - expand key directly in byte array
+                       expandedKey = new byte [exKey.Length << 2];
+                       int k = 0;
+                       for (int i=0; i < exKey.Length; i++) {
+                               expandedKey [k++] = (byte) (exKey[i] >> 24);
+                               expandedKey [k++] = (byte) ((exKey[i] >> 16) & 0xff);
+                               expandedKey [k++] = (byte) ((exKey[i] >> 8) & 0xff);
+                               expandedKey [k++] = (byte) (exKey[i] & 0xff);
+                       }
+               }
+       
+               // note: this method is guaranteed to be called with a valid blocksize
+               // for both input and output
+               protected override void ECB (byte[] input, byte[] output) 
+               {
+                       int pos, ori;
+                       for (pos = 0; pos < input.Length; pos++)
+                               state [pos] = input [pos];
+       
+                       if (encrypt) {
+                               // inline AddRoundKey (0, true);
+                               int roundoffset = 0;
+                               int p = 0;
+                               for (pos = 0; pos < state.Length; pos++)
+                                       state [pos] ^= expandedKey [p++];
+       
+                               for (int round = 1; round < Nr; round++) {
+                                       // inline ByteSub (true);
+                                       for (pos = 0; pos < state.Length; pos++)
+                                               state [pos] = sbox [state [pos]];
+       
+                                       ShiftRow (true);
+       
+                                       // inline MixColumn ();
+                                       pos = 0;
+                                       ori = 0;
+                                       for (int col = 0; col < Nb; col++) {
+                                               byte s0 = state [pos++];
+                                               byte s1 = state [pos++];
+                                               byte s2 = state [pos++];
+                                               byte s3 = state [pos++];
+                                               state [ori++] = (byte) (mult2 [s0] ^ mult3 [s1] ^ s2 ^ s3);
+                                               state [ori++] = (byte) (mult2 [s1] ^ mult3 [s2] ^ s3 ^ s0);
+                                               state [ori++] = (byte) (mult2 [s2] ^ mult3 [s3] ^ s0 ^ s1);
+                                               state [ori++] = (byte) (mult2 [s3] ^ mult3 [s0] ^ s1 ^ s2);
+                                       }
+       
+                                       // inline AddRoundKey (round, true);
+                                       roundoffset += Nb;
+                                       p = (roundoffset << 2);
+                                       for (pos = 0; pos < state.Length; pos++)
+                                               state [pos] ^= expandedKey [p++];
+                               }
                                // inline ByteSub (true);
                                for (pos = 0; pos < state.Length; pos++)
                                        state [pos] = sbox [state [pos]];
-
+       
                                ShiftRow (true);
-
-                               // inline MixColumn ();
-                               pos = 0;
-                               ori = 0;
-                               for (int col = 0; col < Nb; col++) {
-                                       byte s0 = state [pos++];
-                                       byte s1 = state [pos++];
-                                       byte s2 = state [pos++];
-                                       byte s3 = state [pos++];
-                                       state [ori++] = (byte) (mult2 [s0] ^ mult3 [s1] ^ s2 ^ s3);
-                                       state [ori++] = (byte) (mult2 [s1] ^ mult3 [s2] ^ s3 ^ s0);
-                                       state [ori++] = (byte) (mult2 [s2] ^ mult3 [s3] ^ s0 ^ s1);
-                                       state [ori++] = (byte) (mult2 [s3] ^ mult3 [s0] ^ s1 ^ s2);
-                               }
-
-                               // inline AddRoundKey (round, true);
+       
+                               // inline AddRoundKey (Nr, true);
                                roundoffset += Nb;
                                p = (roundoffset << 2);
                                for (pos = 0; pos < state.Length; pos++)
                                        state [pos] ^= expandedKey [p++];
                        }
-                       // inline ByteSub (true);
-                       for (pos = 0; pos < state.Length; pos++)
-                               state [pos] = sbox [state [pos]];
-
-                       ShiftRow (true);
-
-                       // inline AddRoundKey (Nr, true);
-                       roundoffset += Nb;
-                       p = (roundoffset << 2);
-                       for (pos = 0; pos < state.Length; pos++)
-                               state [pos] ^= expandedKey [p++];
-               }
-               else {
-                       // inline AddRoundKey (0, false);
-                       int roundoffset = Nb * Nr;
-                       int p = (roundoffset << 2);
-                       for (pos = 0; pos < state.Length; pos++)
-                               state [pos] ^= expandedKey [p++];
-
-                        ShiftRow (false);
-                       // inline ByteSub (false);
-                       for (pos = 0; pos < state.Length; pos++)
-                               state [pos] = invSbox [state [pos]];
-
-                       for (int round = 1; round < Nr; round++) {
-                               // inline AddRoundKey (round, false);
-                               roundoffset -= Nb;
-                               p = (roundoffset << 2);
+                       else {
+                               // inline AddRoundKey (0, false);
+                               int roundoffset = Nb * Nr;
+                               int p = (roundoffset << 2);
                                for (pos = 0; pos < state.Length; pos++)
                                        state [pos] ^= expandedKey [p++];
-
-                               // inline InvMixColumn ();
-                               pos = 0;
-                               ori = 0;
-                               for (int col = 0; col < Nb; col++) {
-                                       byte s0 = state [pos++];
-                                       byte s1 = state [pos++];
-                                       byte s2 = state [pos++];
-                                       byte s3 = state [pos++];
-                                       state [ori++] = (byte) (multE [s0] ^ multB [s1] ^ multD [s2] ^ mult9 [s3]);
-                                       state [ori++] = (byte) (multE [s1] ^ multB [s2] ^ multD [s3] ^ mult9 [s0]);
-                                       state [ori++] = (byte) (multE [s2] ^ multB [s3] ^ multD [s0] ^ mult9 [s1]);
-                                       state [ori++] = (byte) (multE [s3] ^ multB [s0] ^ multD [s1] ^ mult9 [s2]);
-                               }
-
-                               ShiftRow (false);
-
+       
+                               ShiftRow (false);
                                // inline ByteSub (false);
                                for (pos = 0; pos < state.Length; pos++)
                                        state [pos] = invSbox [state [pos]];
+       
+                               for (int round = 1; round < Nr; round++) {
+                                       // inline AddRoundKey (round, false);
+                                       roundoffset -= Nb;
+                                       p = (roundoffset << 2);
+                                       for (pos = 0; pos < state.Length; pos++)
+                                               state [pos] ^= expandedKey [p++];
+       
+                                       // inline InvMixColumn ();
+                                       pos = 0;
+                                       ori = 0;
+                                       for (int col = 0; col < Nb; col++) {
+                                               byte s0 = state [pos++];
+                                               byte s1 = state [pos++];
+                                               byte s2 = state [pos++];
+                                               byte s3 = state [pos++];
+                                               state [ori++] = (byte) (multE [s0] ^ multB [s1] ^ multD [s2] ^ mult9 [s3]);
+                                               state [ori++] = (byte) (multE [s1] ^ multB [s2] ^ multD [s3] ^ mult9 [s0]);
+                                               state [ori++] = (byte) (multE [s2] ^ multB [s3] ^ multD [s0] ^ mult9 [s1]);
+                                               state [ori++] = (byte) (multE [s3] ^ multB [s0] ^ multD [s1] ^ mult9 [s2]);
+                                       }
+       
+                                       ShiftRow (false);
+       
+                                       // inline ByteSub (false);
+                                       for (pos = 0; pos < state.Length; pos++)
+                                               state [pos] = invSbox [state [pos]];
+                               }
+       
+                               // inline AddRoundKey (Nr, false);
+                               roundoffset -= Nb;
+                               p = (roundoffset << 2);
+                               for (pos = 0; pos < state.Length; pos++)
+                                       state [pos] ^= expandedKey [p++];
                        }
-
-                       // inline AddRoundKey (Nr, false);
-                       roundoffset -= Nb;
-                       p = (roundoffset << 2);
+       
+                       for (pos = 0; pos < input.Length; pos++)
+                               output [pos] = state [pos];
+               }
+       
+               private void ShiftRow (bool encrypt)
+               {
+                       byte[] shifts = encrypt ? eshifts : dshifts;
+                       int pos = 0;
+                       for (int col = 0; col < Nb; col++) {
+                               shifttemp [pos] = state [pos++];
+       
+                               int source_col = (col + shifts [0]);
+                               if (source_col >= Nb) source_col -= Nb;
+                               shifttemp [pos++] = state [(source_col << 2) + 1];
+       
+                               source_col = (col + shifts [1]);
+                               if (source_col >= Nb) source_col -= Nb;
+                               shifttemp [pos++] = state [(source_col << 2) + 2];
+       
+                               source_col = (col + shifts [2]);
+                               if (source_col >= Nb) source_col -= Nb;
+                               shifttemp [pos++] = state [(source_col << 2) + 3];
+                       }
+       
                        for (pos = 0; pos < state.Length; pos++)
-                               state [pos] ^= expandedKey [p++];
+                               state [pos] = shifttemp [pos];
                }
-
-               for (pos = 0; pos < input.Length; pos++)
-                       output [pos] = state [pos];
-       }
-
-       private void ShiftRow (bool encrypt)
-       {
-               byte[] shifts = encrypt ? eshifts : dshifts;
-               int pos = 0;
-               for (int col = 0; col < Nb; col++) {
-                       shifttemp [pos] = state [pos++];
-
-                       int source_col = (col + shifts [0]);
-                       if (source_col >= Nb) source_col -= Nb;
-                       shifttemp [pos++] = state [(source_col << 2) + 1];
-
-                       source_col = (col + shifts [1]);
-                       if (source_col >= Nb) source_col -= Nb;
-                       shifttemp [pos++] = state [(source_col << 2) + 2];
-
-                       source_col = (col + shifts [2]);
-                       if (source_col >= Nb) source_col -= Nb;
-                       shifttemp [pos++] = state [(source_col << 2) + 3];
+       
+               private Int32 SubByte (Int32 a)
+               {
+                       Int32 value = 0xff & a;
+                       Int32 result = sbox [value]; 
+                       value = 0xff & (a >> 8);
+                       result |= sbox [value] << 8; 
+                       value = 0xff & (a >> 16);
+                       result |= sbox [value] << 16; 
+                       value = 0xff & (a >> 24);
+                       return result | (sbox [value] << 24);
                }
-
-               for (pos = 0; pos < state.Length; pos++)
-                       state [pos] = shifttemp [pos];
-       }
-
-       private Int32 SubByte (Int32 a)
-       {
-               Int32 value = 0xff & a;
-               Int32 result = sbox [value]; 
-               value = 0xff & (a >> 8);
-               result |= sbox [value] << 8; 
-               value = 0xff & (a >> 16);
-               result |= sbox [value] << 16; 
-               value = 0xff & (a >> 24);
-               return result | (sbox [value] << 24);
+       
+               // Constant tables used in the cipher
+               static byte[] sbox = {
+               99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118, 
+               202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 
+               183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21, 
+               4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117, 
+               9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132, 
+               83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 
+               208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168, 
+               81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, 
+               205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115, 
+               96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 
+               224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 
+               231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 
+               186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 
+               112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 
+               225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223, 
+               140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22 
+               };
+       
+               static byte[] invSbox = {
+               82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158, 129, 243, 215, 251, 
+               124, 227,  57, 130, 155,  47, 255, 135,  52, 142,  67,  68, 196, 222, 233, 203, 
+               84, 123, 148,  50, 166, 194,  35,  61, 238,  76, 149,  11,  66, 250, 195,  78, 
+               8,  46, 161, 102,  40, 217,  36, 178, 118,  91, 162,  73, 109, 139, 209,  37, 
+               114, 248, 246, 100, 134, 104, 152,  22, 212, 164,  92, 204,  93, 101, 182, 146, 
+               108, 112,  72,  80, 253, 237, 185, 218,  94,  21,  70,  87, 167, 141, 157, 132, 
+               144, 216, 171,   0, 140, 188, 211,  10, 247, 228,  88,   5, 184, 179,  69,   6, 
+               208,  44,  30, 143, 202,  63,  15,   2, 193, 175, 189,   3,   1,  19, 138, 107, 
+               58, 145,  17,  65,  79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 
+               150, 172, 116,  34, 231, 173,  53, 133, 226, 249,  55, 232,  28, 117, 223, 110, 
+               71, 241,  26, 113,  29,  41, 197, 137, 111, 183,  98,  14, 170,  24, 190,  27, 
+               252,  86,  62,  75, 198, 210, 121,  32, 154, 219, 192, 254, 120, 205,  90, 244, 
+               31, 221, 168,  51, 136,   7, 199,  49, 177,  18,  16,  89,  39, 128, 236,  95, 
+               96,  81, 127, 169,  25, 181,  74,  13,  45, 229, 122, 159, 147, 201, 156, 239, 
+               160, 224,  59,  77, 174,  42, 245, 176, 200, 235, 187,  60, 131,  83, 153,  97, 
+               23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,  85,  33,  12, 125
+               };
+       
+       /* Original tables - DO NOT DELETE !
+        *      static byte[] logtable = {
+               0,   0,  25,   1,  50,   2,  26, 198,  75, 199,  27, 104,  51, 238, 223,   3, 
+               100,   4, 224,  14,  52, 141, 129, 239,  76, 113,   8, 200, 248, 105,  28, 193, 
+               125, 194,  29, 181, 249, 185,  39, 106,  77, 228, 166, 114, 154, 201,   9, 120, 
+               101,  47, 138,   5,  33,  15, 225,  36,  18, 240, 130,  69,  53, 147, 218, 142, 
+               150, 143, 219, 189,  54, 208, 206, 148,  19,  92, 210, 241,  64,  70, 131,  56, 
+               102, 221, 253,  48, 191,   6, 139,  98, 179,  37, 226, 152,  34, 136, 145,  16, 
+               126, 110,  72, 195, 163, 182,  30,  66,  58, 107,  40,  84, 250, 133,  61, 186, 
+               43, 121,  10,  21, 155, 159,  94, 202,  78, 212, 172, 229, 243, 115, 167,  87, 
+               175,  88, 168,  80, 244, 234, 214, 116,  79, 174, 233, 213, 231, 230, 173, 232, 
+               44, 215, 117, 122, 235,  22,  11, 245,  89, 203,  95, 176, 156, 169,  81, 160, 
+               127,  12, 246, 111,  23, 196,  73, 236, 216,  67,  31,  45, 164, 118, 123, 183, 
+               204, 187,  62,  90, 251,  96, 177, 134,  59,  82, 161, 108, 170,  85,  41, 157, 
+               151, 178, 135, 144,  97, 190, 220, 252, 188, 149, 207, 205,  55,  63,  91, 209, 
+               83,  57, 132,  60,  65, 162, 109,  71,  20,  42, 158,  93,  86, 242, 211, 171, 
+               68,  17, 146, 217,  35,  32,  46, 137, 180, 124, 184,  38, 119, 153, 227, 165, 
+               103,  74, 237, 222, 197,  49, 254,  24,  13,  99, 140, 128, 192, 247, 112,   7 
+               };
+       
+               static byte[] alogtable = {
+               1,   3,   5,  15,  17,  51,  85, 255,  26,  46, 114, 150, 161, 248,  19,  53, 
+               95, 225,  56,  72, 216, 115, 149, 164, 247,   2,   6,  10,  30,  34, 102, 170, 
+               229,  52,  92, 228,  55,  89, 235,  38, 106, 190, 217, 112, 144, 171, 230,  49, 
+               83, 245,   4,  12,  20,  60,  68, 204,  79, 209, 104, 184, 211, 110, 178, 205, 
+               76, 212, 103, 169, 224,  59,  77, 215,  98, 166, 241,   8,  24,  40, 120, 136, 
+               131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206,  73, 219, 118, 154, 
+               181, 196,  87, 249,  16,  48,  80, 240,  11,  29,  39, 105, 187, 214,  97, 163, 
+               254,  25,  43, 125, 135, 146, 173, 236,  47, 113, 147, 174, 233,  32,  96, 160, 
+               251,  22,  58,  78, 210, 109, 183, 194,  93, 231,  50,  86, 250,  21,  63,  65, 
+               195,  94, 226,  61,  71, 201,  64, 192,  91, 237,  44, 116, 156, 191, 218, 117, 
+               159, 186, 213, 100, 172, 239,  42, 126, 130, 157, 188, 223, 122, 142, 137, 128, 
+               155, 182, 193,  88, 232,  35, 101, 175, 234,  37, 111, 177, 200,  67, 197,  84, 
+               252,  31,  33,  99, 165, 244,   7,   9,  27,  45, 119, 153, 176, 203,  70, 202, 
+               69, 207,  74, 222, 121, 139, 134, 145, 168, 227,  62,  66, 198,  81, 243,  14, 
+               18,  54,  90, 238,  41, 123, 141, 140, 143, 138, 133, 148, 167, 242,  13,  23, 
+               57,  75, 221, 124, 132, 151, 162, 253,  28,  36, 108, 180, 199,  82, 246,   1 
+               };*/
+       
+               static byte[] mult2 = { 
+               0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 
+               0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 
+               0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 
+               0x60, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 
+               0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 
+               0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0xBE, 
+               0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, 
+               0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, 0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE, 
+               0x1B, 0x19, 0x1F, 0x1D, 0x13, 0x11, 0x17, 0x15, 0x0B, 0x09, 0x0F, 0x0D, 0x03, 0x01, 0x07, 0x05, 
+               0x3B, 0x39, 0x3F, 0x3D, 0x33, 0x31, 0x37, 0x35, 0x2B, 0x29, 0x2F, 0x2D, 0x23, 0x21, 0x27, 0x25, 
+               0x5B, 0x59, 0x5F, 0x5D, 0x53, 0x51, 0x57, 0x55, 0x4B, 0x49, 0x4F, 0x4D, 0x43, 0x41, 0x47, 0x45, 
+               0x7B, 0x79, 0x7F, 0x7D, 0x73, 0x71, 0x77, 0x75, 0x6B, 0x69, 0x6F, 0x6D, 0x63, 0x61, 0x67, 0x65, 
+               0x9B, 0x99, 0x9F, 0x9D, 0x93, 0x91, 0x97, 0x95, 0x8B, 0x89, 0x8F, 0x8D, 0x83, 0x81, 0x87, 0x85, 
+               0xBB, 0xB9, 0xBF, 0xBD, 0xB3, 0xB1, 0xB7, 0xB5, 0xAB, 0xA9, 0xAF, 0xAD, 0xA3, 0xA1, 0xA7, 0xA5, 
+               0xDB, 0xD9, 0xDF, 0xDD, 0xD3, 0xD1, 0xD7, 0xD5, 0xCB, 0xC9, 0xCF, 0xCD, 0xC3, 0xC1, 0xC7, 0xC5, 
+               0xFB, 0xF9, 0xFF, 0xFD, 0xF3, 0xF1, 0xF7, 0xF5, 0xEB, 0xE9, 0xEF, 0xED, 0xE3, 0xE1, 0xE7, 0xE5
+               };
+       
+               static byte[] mult3 = {
+               0x00, 0x03, 0x06, 0x05, 0x0C, 0x0F, 0x0A, 0x09, 0x18, 0x1B, 0x1E, 0x1D, 0x14, 0x17, 0x12, 0x11, 
+               0x30, 0x33, 0x36, 0x35, 0x3C, 0x3F, 0x3A, 0x39, 0x28, 0x2B, 0x2E, 0x2D, 0x24, 0x27, 0x22, 0x21, 
+               0x60, 0x63, 0x66, 0x65, 0x6C, 0x6F, 0x6A, 0x69, 0x78, 0x7B, 0x7E, 0x7D, 0x74, 0x77, 0x72, 0x71, 
+               0x50, 0x53, 0x56, 0x55, 0x5C, 0x5F, 0x5A, 0x59, 0x48, 0x4B, 0x4E, 0x4D, 0x44, 0x47, 0x42, 0x41, 
+               0xC0, 0xC3, 0xC6, 0xC5, 0xCC, 0xCF, 0xCA, 0xC9, 0xD8, 0xDB, 0xDE, 0xDD, 0xD4, 0xD7, 0xD2, 0xD1, 
+               0xF0, 0xF3, 0xF6, 0xF5, 0xFC, 0xFF, 0xFA, 0xF9, 0xE8, 0xEB, 0xEE, 0xED, 0xE4, 0xE7, 0xE2, 0xE1, 
+               0xA0, 0xA3, 0xA6, 0xA5, 0xAC, 0xAF, 0xAA, 0xA9, 0xB8, 0xBB, 0xBE, 0xBD, 0xB4, 0xB7, 0xB2, 0xB1, 
+               0x90, 0x93, 0x96, 0x95, 0x9C, 0x9F, 0x9A, 0x99, 0x88, 0x8B, 0x8E, 0x8D, 0x84, 0x87, 0x82, 0x81, 
+               0x9B, 0x98, 0x9D, 0x9E, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8F, 0x8C, 0x89, 0x8A, 
+               0xAB, 0xA8, 0xAD, 0xAE, 0xA7, 0xA4, 0xA1, 0xA2, 0xB3, 0xB0, 0xB5, 0xB6, 0xBF, 0xBC, 0xB9, 0xBA, 
+               0xFB, 0xF8, 0xFD, 0xFE, 0xF7, 0xF4, 0xF1, 0xF2, 0xE3, 0xE0, 0xE5, 0xE6, 0xEF, 0xEC, 0xE9, 0xEA, 
+               0xCB, 0xC8, 0xCD, 0xCE, 0xC7, 0xC4, 0xC1, 0xC2, 0xD3, 0xD0, 0xD5, 0xD6, 0xDF, 0xDC, 0xD9, 0xDA, 
+               0x5B, 0x58, 0x5D, 0x5E, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4F, 0x4C, 0x49, 0x4A, 
+               0x6B, 0x68, 0x6D, 0x6E, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7F, 0x7C, 0x79, 0x7A, 
+               0x3B, 0x38, 0x3D, 0x3E, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2F, 0x2C, 0x29, 0x2A, 
+               0x0B, 0x08, 0x0D, 0x0E, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1F, 0x1C, 0x19, 0x1A 
+               };
+       
+               static byte[] multE = {
+               0x00, 0x0E, 0x1C, 0x12, 0x38, 0x36, 0x24, 0x2A, 0x70, 0x7E, 0x6C, 0x62, 0x48, 0x46, 0x54, 0x5A, 
+               0xE0, 0xEE, 0xFC, 0xF2, 0xD8, 0xD6, 0xC4, 0xCA, 0x90, 0x9E, 0x8C, 0x82, 0xA8, 0xA6, 0xB4, 0xBA, 
+               0xDB, 0xD5, 0xC7, 0xC9, 0xE3, 0xED, 0xFF, 0xF1, 0xAB, 0xA5, 0xB7, 0xB9, 0x93, 0x9D, 0x8F, 0x81, 
+               0x3B, 0x35, 0x27, 0x29, 0x03, 0x0D, 0x1F, 0x11, 0x4B, 0x45, 0x57, 0x59, 0x73, 0x7D, 0x6F, 0x61, 
+               0xAD, 0xA3, 0xB1, 0xBF, 0x95, 0x9B, 0x89, 0x87, 0xDD, 0xD3, 0xC1, 0xCF, 0xE5, 0xEB, 0xF9, 0xF7, 
+               0x4D, 0x43, 0x51, 0x5F, 0x75, 0x7B, 0x69, 0x67, 0x3D, 0x33, 0x21, 0x2F, 0x05, 0x0B, 0x19, 0x17, 
+               0x76, 0x78, 0x6A, 0x64, 0x4E, 0x40, 0x52, 0x5C, 0x06, 0x08, 0x1A, 0x14, 0x3E, 0x30, 0x22, 0x2C, 
+               0x96, 0x98, 0x8A, 0x84, 0xAE, 0xA0, 0xB2, 0xBC, 0xE6, 0xE8, 0xFA, 0xF4, 0xDE, 0xD0, 0xC2, 0xCC, 
+               0x41, 0x4F, 0x5D, 0x53, 0x79, 0x77, 0x65, 0x6B, 0x31, 0x3F, 0x2D, 0x23, 0x09, 0x07, 0x15, 0x1B, 
+               0xA1, 0xAF, 0xBD, 0xB3, 0x99, 0x97, 0x85, 0x8B, 0xD1, 0xDF, 0xCD, 0xC3, 0xE9, 0xE7, 0xF5, 0xFB, 
+               0x9A, 0x94, 0x86, 0x88, 0xA2, 0xAC, 0xBE, 0xB0, 0xEA, 0xE4, 0xF6, 0xF8, 0xD2, 0xDC, 0xCE, 0xC0, 
+               0x7A, 0x74, 0x66, 0x68, 0x42, 0x4C, 0x5E, 0x50, 0x0A, 0x04, 0x16, 0x18, 0x32, 0x3C, 0x2E, 0x20, 
+               0xEC, 0xE2, 0xF0, 0xFE, 0xD4, 0xDA, 0xC8, 0xC6, 0x9C, 0x92, 0x80, 0x8E, 0xA4, 0xAA, 0xB8, 0xB6, 
+               0x0C, 0x02, 0x10, 0x1E, 0x34, 0x3A, 0x28, 0x26, 0x7C, 0x72, 0x60, 0x6E, 0x44, 0x4A, 0x58, 0x56, 
+               0x37, 0x39, 0x2B, 0x25, 0x0F, 0x01, 0x13, 0x1D, 0x47, 0x49, 0x5B, 0x55, 0x7F, 0x71, 0x63, 0x6D, 
+               0xD7, 0xD9, 0xCB, 0xC5, 0xEF, 0xE1, 0xF3, 0xFD, 0xA7, 0xA9, 0xBB, 0xB5, 0x9F, 0x91, 0x83, 0x8D, 
+               };
+       
+               static byte[] multB = {
+               0x00, 0x0B, 0x16, 0x1D, 0x2C, 0x27, 0x3A, 0x31, 0x58, 0x53, 0x4E, 0x45, 0x74, 0x7F, 0x62, 0x69, 
+               0xB0, 0xBB, 0xA6, 0xAD, 0x9C, 0x97, 0x8A, 0x81, 0xE8, 0xE3, 0xFE, 0xF5, 0xC4, 0xCF, 0xD2, 0xD9, 
+               0x7B, 0x70, 0x6D, 0x66, 0x57, 0x5C, 0x41, 0x4A, 0x23, 0x28, 0x35, 0x3E, 0x0F, 0x04, 0x19, 0x12, 
+               0xCB, 0xC0, 0xDD, 0xD6, 0xE7, 0xEC, 0xF1, 0xFA, 0x93, 0x98, 0x85, 0x8E, 0xBF, 0xB4, 0xA9, 0xA2, 
+               0xF6, 0xFD, 0xE0, 0xEB, 0xDA, 0xD1, 0xCC, 0xC7, 0xAE, 0xA5, 0xB8, 0xB3, 0x82, 0x89, 0x94, 0x9F, 
+               0x46, 0x4D, 0x50, 0x5B, 0x6A, 0x61, 0x7C, 0x77, 0x1E, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2F, 
+               0x8D, 0x86, 0x9B, 0x90, 0xA1, 0xAA, 0xB7, 0xBC, 0xD5, 0xDE, 0xC3, 0xC8, 0xF9, 0xF2, 0xEF, 0xE4, 
+               0x3D, 0x36, 0x2B, 0x20, 0x11, 0x1A, 0x07, 0x0C, 0x65, 0x6E, 0x73, 0x78, 0x49, 0x42, 0x5F, 0x54, 
+               0xF7, 0xFC, 0xE1, 0xEA, 0xDB, 0xD0, 0xCD, 0xC6, 0xAF, 0xA4, 0xB9, 0xB2, 0x83, 0x88, 0x95, 0x9E, 
+               0x47, 0x4C, 0x51, 0x5A, 0x6B, 0x60, 0x7D, 0x76, 0x1F, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2E, 
+               0x8C, 0x87, 0x9A, 0x91, 0xA0, 0xAB, 0xB6, 0xBD, 0xD4, 0xDF, 0xC2, 0xC9, 0xF8, 0xF3, 0xEE, 0xE5, 
+               0x3C, 0x37, 0x2A, 0x21, 0x10, 0x1B, 0x06, 0x0D, 0x64, 0x6F, 0x72, 0x79, 0x48, 0x43, 0x5E, 0x55, 
+               0x01, 0x0A, 0x17, 0x1C, 0x2D, 0x26, 0x3B, 0x30, 0x59, 0x52, 0x4F, 0x44, 0x75, 0x7E, 0x63, 0x68, 
+               0xB1, 0xBA, 0xA7, 0xAC, 0x9D, 0x96, 0x8B, 0x80, 0xE9, 0xE2, 0xFF, 0xF4, 0xC5, 0xCE, 0xD3, 0xD8, 
+               0x7A, 0x71, 0x6C, 0x67, 0x56, 0x5D, 0x40, 0x4B, 0x22, 0x29, 0x34, 0x3F, 0x0E, 0x05, 0x18, 0x13, 
+               0xCA, 0xC1, 0xDC, 0xD7, 0xE6, 0xED, 0xF0, 0xFB, 0x92, 0x99, 0x84, 0x8F, 0xBE, 0xB5, 0xA8, 0xA3, 
+               };
+       
+               static byte[] multD = {
+               0x00, 0x0D, 0x1A, 0x17, 0x34, 0x39, 0x2E, 0x23, 0x68, 0x65, 0x72, 0x7F, 0x5C, 0x51, 0x46, 0x4B, 
+               0xD0, 0xDD, 0xCA, 0xC7, 0xE4, 0xE9, 0xFE, 0xF3, 0xB8, 0xB5, 0xA2, 0xAF, 0x8C, 0x81, 0x96, 0x9B, 
+               0xBB, 0xB6, 0xA1, 0xAC, 0x8F, 0x82, 0x95, 0x98, 0xD3, 0xDE, 0xC9, 0xC4, 0xE7, 0xEA, 0xFD, 0xF0, 
+               0x6B, 0x66, 0x71, 0x7C, 0x5F, 0x52, 0x45, 0x48, 0x03, 0x0E, 0x19, 0x14, 0x37, 0x3A, 0x2D, 0x20, 
+               0x6D, 0x60, 0x77, 0x7A, 0x59, 0x54, 0x43, 0x4E, 0x05, 0x08, 0x1F, 0x12, 0x31, 0x3C, 0x2B, 0x26, 
+               0xBD, 0xB0, 0xA7, 0xAA, 0x89, 0x84, 0x93, 0x9E, 0xD5, 0xD8, 0xCF, 0xC2, 0xE1, 0xEC, 0xFB, 0xF6, 
+               0xD6, 0xDB, 0xCC, 0xC1, 0xE2, 0xEF, 0xF8, 0xF5, 0xBE, 0xB3, 0xA4, 0xA9, 0x8A, 0x87, 0x90, 0x9D, 
+               0x06, 0x0B, 0x1C, 0x11, 0x32, 0x3F, 0x28, 0x25, 0x6E, 0x63, 0x74, 0x79, 0x5A, 0x57, 0x40, 0x4D, 
+               0xDA, 0xD7, 0xC0, 0xCD, 0xEE, 0xE3, 0xF4, 0xF9, 0xB2, 0xBF, 0xA8, 0xA5, 0x86, 0x8B, 0x9C, 0x91, 
+               0x0A, 0x07, 0x10, 0x1D, 0x3E, 0x33, 0x24, 0x29, 0x62, 0x6F, 0x78, 0x75, 0x56, 0x5B, 0x4C, 0x41, 
+               0x61, 0x6C, 0x7B, 0x76, 0x55, 0x58, 0x4F, 0x42, 0x09, 0x04, 0x13, 0x1E, 0x3D, 0x30, 0x27, 0x2A, 
+               0xB1, 0xBC, 0xAB, 0xA6, 0x85, 0x88, 0x9F, 0x92, 0xD9, 0xD4, 0xC3, 0xCE, 0xED, 0xE0, 0xF7, 0xFA, 
+               0xB7, 0xBA, 0xAD, 0xA0, 0x83, 0x8E, 0x99, 0x94, 0xDF, 0xD2, 0xC5, 0xC8, 0xEB, 0xE6, 0xF1, 0xFC, 
+               0x67, 0x6A, 0x7D, 0x70, 0x53, 0x5E, 0x49, 0x44, 0x0F, 0x02, 0x15, 0x18, 0x3B, 0x36, 0x21, 0x2C, 
+               0x0C, 0x01, 0x16, 0x1B, 0x38, 0x35, 0x22, 0x2F, 0x64, 0x69, 0x7E, 0x73, 0x50, 0x5D, 0x4A, 0x47, 
+               0xDC, 0xD1, 0xC6, 0xCB, 0xE8, 0xE5, 0xF2, 0xFF, 0xB4, 0xB9, 0xAE, 0xA3, 0x80, 0x8D, 0x9A, 0x97, 
+               };
+       
+               static byte[] mult9 = {
+               0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F, 0x48, 0x41, 0x5A, 0x53, 0x6C, 0x65, 0x7E, 0x77, 
+               0x90, 0x99, 0x82, 0x8B, 0xB4, 0xBD, 0xA6, 0xAF, 0xD8, 0xD1, 0xCA, 0xC3, 0xFC, 0xF5, 0xEE, 0xE7, 
+               0x3B, 0x32, 0x29, 0x20, 0x1F, 0x16, 0x0D, 0x04, 0x73, 0x7A, 0x61, 0x68, 0x57, 0x5E, 0x45, 0x4C, 
+               0xAB, 0xA2, 0xB9, 0xB0, 0x8F, 0x86, 0x9D, 0x94, 0xE3, 0xEA, 0xF1, 0xF8, 0xC7, 0xCE, 0xD5, 0xDC, 
+               0x76, 0x7F, 0x64, 0x6D, 0x52, 0x5B, 0x40, 0x49, 0x3E, 0x37, 0x2C, 0x25, 0x1A, 0x13, 0x08, 0x01, 
+               0xE6, 0xEF, 0xF4, 0xFD, 0xC2, 0xCB, 0xD0, 0xD9, 0xAE, 0xA7, 0xBC, 0xB5, 0x8A, 0x83, 0x98, 0x91, 
+               0x4D, 0x44, 0x5F, 0x56, 0x69, 0x60, 0x7B, 0x72, 0x05, 0x0C, 0x17, 0x1E, 0x21, 0x28, 0x33, 0x3A, 
+               0xDD, 0xD4, 0xCF, 0xC6, 0xF9, 0xF0, 0xEB, 0xE2, 0x95, 0x9C, 0x87, 0x8E, 0xB1, 0xB8, 0xA3, 0xAA, 
+               0xEC, 0xE5, 0xFE, 0xF7, 0xC8, 0xC1, 0xDA, 0xD3, 0xA4, 0xAD, 0xB6, 0xBF, 0x80, 0x89, 0x92, 0x9B, 
+               0x7C, 0x75, 0x6E, 0x67, 0x58, 0x51, 0x4A, 0x43, 0x34, 0x3D, 0x26, 0x2F, 0x10, 0x19, 0x02, 0x0B, 
+               0xD7, 0xDE, 0xC5, 0xCC, 0xF3, 0xFA, 0xE1, 0xE8, 0x9F, 0x96, 0x8D, 0x84, 0xBB, 0xB2, 0xA9, 0xA0, 
+               0x47, 0x4E, 0x55, 0x5C, 0x63, 0x6A, 0x71, 0x78, 0x0F, 0x06, 0x1D, 0x14, 0x2B, 0x22, 0x39, 0x30, 
+               0x9A, 0x93, 0x88, 0x81, 0xBE, 0xB7, 0xAC, 0xA5, 0xD2, 0xDB, 0xC0, 0xC9, 0xF6, 0xFF, 0xE4, 0xED, 
+               0x0A, 0x03, 0x18, 0x11, 0x2E, 0x27, 0x3C, 0x35, 0x42, 0x4B, 0x50, 0x59, 0x66, 0x6F, 0x74, 0x7D, 
+               0xA1, 0xA8, 0xB3, 0xBA, 0x85, 0x8C, 0x97, 0x9E, 0xE9, 0xE0, 0xFB, 0xF2, 0xCD, 0xC4, 0xDF, 0xD6, 
+               0x31, 0x38, 0x23, 0x2A, 0x15, 0x1C, 0x07, 0x0E, 0x79, 0x70, 0x6B, 0x62, 0x5D, 0x54, 0x4F, 0x46, 
+               };
+       
        }
-
-       // Constant tables used in the cipher
-       static byte[] sbox = {
-       99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118, 
-       202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 
-       183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21, 
-       4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117, 
-       9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132, 
-       83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 
-       208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168, 
-       81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, 
-       205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115, 
-       96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 
-       224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 
-       231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 
-       186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 
-       112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 
-       225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223, 
-       140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22 
-       };
-
-       static byte[] invSbox = {
-       82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158, 129, 243, 215, 251, 
-       124, 227,  57, 130, 155,  47, 255, 135,  52, 142,  67,  68, 196, 222, 233, 203, 
-       84, 123, 148,  50, 166, 194,  35,  61, 238,  76, 149,  11,  66, 250, 195,  78, 
-       8,  46, 161, 102,  40, 217,  36, 178, 118,  91, 162,  73, 109, 139, 209,  37, 
-       114, 248, 246, 100, 134, 104, 152,  22, 212, 164,  92, 204,  93, 101, 182, 146, 
-       108, 112,  72,  80, 253, 237, 185, 218,  94,  21,  70,  87, 167, 141, 157, 132, 
-       144, 216, 171,   0, 140, 188, 211,  10, 247, 228,  88,   5, 184, 179,  69,   6, 
-       208,  44,  30, 143, 202,  63,  15,   2, 193, 175, 189,   3,   1,  19, 138, 107, 
-       58, 145,  17,  65,  79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 
-       150, 172, 116,  34, 231, 173,  53, 133, 226, 249,  55, 232,  28, 117, 223, 110, 
-       71, 241,  26, 113,  29,  41, 197, 137, 111, 183,  98,  14, 170,  24, 190,  27, 
-       252,  86,  62,  75, 198, 210, 121,  32, 154, 219, 192, 254, 120, 205,  90, 244, 
-       31, 221, 168,  51, 136,   7, 199,  49, 177,  18,  16,  89,  39, 128, 236,  95, 
-       96,  81, 127, 169,  25, 181,  74,  13,  45, 229, 122, 159, 147, 201, 156, 239, 
-       160, 224,  59,  77, 174,  42, 245, 176, 200, 235, 187,  60, 131,  83, 153,  97, 
-       23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,  85,  33,  12, 125
-       };
-
-/* Original tables - DO NOT DELETE !
- *     static byte[] logtable = {
-       0,   0,  25,   1,  50,   2,  26, 198,  75, 199,  27, 104,  51, 238, 223,   3, 
-       100,   4, 224,  14,  52, 141, 129, 239,  76, 113,   8, 200, 248, 105,  28, 193, 
-       125, 194,  29, 181, 249, 185,  39, 106,  77, 228, 166, 114, 154, 201,   9, 120, 
-       101,  47, 138,   5,  33,  15, 225,  36,  18, 240, 130,  69,  53, 147, 218, 142, 
-       150, 143, 219, 189,  54, 208, 206, 148,  19,  92, 210, 241,  64,  70, 131,  56, 
-       102, 221, 253,  48, 191,   6, 139,  98, 179,  37, 226, 152,  34, 136, 145,  16, 
-       126, 110,  72, 195, 163, 182,  30,  66,  58, 107,  40,  84, 250, 133,  61, 186, 
-       43, 121,  10,  21, 155, 159,  94, 202,  78, 212, 172, 229, 243, 115, 167,  87, 
-       175,  88, 168,  80, 244, 234, 214, 116,  79, 174, 233, 213, 231, 230, 173, 232, 
-       44, 215, 117, 122, 235,  22,  11, 245,  89, 203,  95, 176, 156, 169,  81, 160, 
-       127,  12, 246, 111,  23, 196,  73, 236, 216,  67,  31,  45, 164, 118, 123, 183, 
-       204, 187,  62,  90, 251,  96, 177, 134,  59,  82, 161, 108, 170,  85,  41, 157, 
-       151, 178, 135, 144,  97, 190, 220, 252, 188, 149, 207, 205,  55,  63,  91, 209, 
-       83,  57, 132,  60,  65, 162, 109,  71,  20,  42, 158,  93,  86, 242, 211, 171, 
-       68,  17, 146, 217,  35,  32,  46, 137, 180, 124, 184,  38, 119, 153, 227, 165, 
-       103,  74, 237, 222, 197,  49, 254,  24,  13,  99, 140, 128, 192, 247, 112,   7 
-       };
-
-       static byte[] alogtable = {
-       1,   3,   5,  15,  17,  51,  85, 255,  26,  46, 114, 150, 161, 248,  19,  53, 
-       95, 225,  56,  72, 216, 115, 149, 164, 247,   2,   6,  10,  30,  34, 102, 170, 
-       229,  52,  92, 228,  55,  89, 235,  38, 106, 190, 217, 112, 144, 171, 230,  49, 
-       83, 245,   4,  12,  20,  60,  68, 204,  79, 209, 104, 184, 211, 110, 178, 205, 
-       76, 212, 103, 169, 224,  59,  77, 215,  98, 166, 241,   8,  24,  40, 120, 136, 
-       131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206,  73, 219, 118, 154, 
-       181, 196,  87, 249,  16,  48,  80, 240,  11,  29,  39, 105, 187, 214,  97, 163, 
-       254,  25,  43, 125, 135, 146, 173, 236,  47, 113, 147, 174, 233,  32,  96, 160, 
-       251,  22,  58,  78, 210, 109, 183, 194,  93, 231,  50,  86, 250,  21,  63,  65, 
-       195,  94, 226,  61,  71, 201,  64, 192,  91, 237,  44, 116, 156, 191, 218, 117, 
-       159, 186, 213, 100, 172, 239,  42, 126, 130, 157, 188, 223, 122, 142, 137, 128, 
-       155, 182, 193,  88, 232,  35, 101, 175, 234,  37, 111, 177, 200,  67, 197,  84, 
-       252,  31,  33,  99, 165, 244,   7,   9,  27,  45, 119, 153, 176, 203,  70, 202, 
-       69, 207,  74, 222, 121, 139, 134, 145, 168, 227,  62,  66, 198,  81, 243,  14, 
-       18,  54,  90, 238,  41, 123, 141, 140, 143, 138, 133, 148, 167, 242,  13,  23, 
-       57,  75, 221, 124, 132, 151, 162, 253,  28,  36, 108, 180, 199,  82, 246,   1 
-       };*/
-
-       static byte[] mult2 = { 
-       0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 
-       0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 
-       0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 
-       0x60, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 
-       0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 
-       0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0xBE, 
-       0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, 
-       0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, 0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE, 
-       0x1B, 0x19, 0x1F, 0x1D, 0x13, 0x11, 0x17, 0x15, 0x0B, 0x09, 0x0F, 0x0D, 0x03, 0x01, 0x07, 0x05, 
-       0x3B, 0x39, 0x3F, 0x3D, 0x33, 0x31, 0x37, 0x35, 0x2B, 0x29, 0x2F, 0x2D, 0x23, 0x21, 0x27, 0x25, 
-       0x5B, 0x59, 0x5F, 0x5D, 0x53, 0x51, 0x57, 0x55, 0x4B, 0x49, 0x4F, 0x4D, 0x43, 0x41, 0x47, 0x45, 
-       0x7B, 0x79, 0x7F, 0x7D, 0x73, 0x71, 0x77, 0x75, 0x6B, 0x69, 0x6F, 0x6D, 0x63, 0x61, 0x67, 0x65, 
-       0x9B, 0x99, 0x9F, 0x9D, 0x93, 0x91, 0x97, 0x95, 0x8B, 0x89, 0x8F, 0x8D, 0x83, 0x81, 0x87, 0x85, 
-       0xBB, 0xB9, 0xBF, 0xBD, 0xB3, 0xB1, 0xB7, 0xB5, 0xAB, 0xA9, 0xAF, 0xAD, 0xA3, 0xA1, 0xA7, 0xA5, 
-       0xDB, 0xD9, 0xDF, 0xDD, 0xD3, 0xD1, 0xD7, 0xD5, 0xCB, 0xC9, 0xCF, 0xCD, 0xC3, 0xC1, 0xC7, 0xC5, 
-       0xFB, 0xF9, 0xFF, 0xFD, 0xF3, 0xF1, 0xF7, 0xF5, 0xEB, 0xE9, 0xEF, 0xED, 0xE3, 0xE1, 0xE7, 0xE5
-       };
-
-       static byte[] mult3 = {
-       0x00, 0x03, 0x06, 0x05, 0x0C, 0x0F, 0x0A, 0x09, 0x18, 0x1B, 0x1E, 0x1D, 0x14, 0x17, 0x12, 0x11, 
-       0x30, 0x33, 0x36, 0x35, 0x3C, 0x3F, 0x3A, 0x39, 0x28, 0x2B, 0x2E, 0x2D, 0x24, 0x27, 0x22, 0x21, 
-       0x60, 0x63, 0x66, 0x65, 0x6C, 0x6F, 0x6A, 0x69, 0x78, 0x7B, 0x7E, 0x7D, 0x74, 0x77, 0x72, 0x71, 
-       0x50, 0x53, 0x56, 0x55, 0x5C, 0x5F, 0x5A, 0x59, 0x48, 0x4B, 0x4E, 0x4D, 0x44, 0x47, 0x42, 0x41, 
-       0xC0, 0xC3, 0xC6, 0xC5, 0xCC, 0xCF, 0xCA, 0xC9, 0xD8, 0xDB, 0xDE, 0xDD, 0xD4, 0xD7, 0xD2, 0xD1, 
-       0xF0, 0xF3, 0xF6, 0xF5, 0xFC, 0xFF, 0xFA, 0xF9, 0xE8, 0xEB, 0xEE, 0xED, 0xE4, 0xE7, 0xE2, 0xE1, 
-       0xA0, 0xA3, 0xA6, 0xA5, 0xAC, 0xAF, 0xAA, 0xA9, 0xB8, 0xBB, 0xBE, 0xBD, 0xB4, 0xB7, 0xB2, 0xB1, 
-       0x90, 0x93, 0x96, 0x95, 0x9C, 0x9F, 0x9A, 0x99, 0x88, 0x8B, 0x8E, 0x8D, 0x84, 0x87, 0x82, 0x81, 
-       0x9B, 0x98, 0x9D, 0x9E, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8F, 0x8C, 0x89, 0x8A, 
-       0xAB, 0xA8, 0xAD, 0xAE, 0xA7, 0xA4, 0xA1, 0xA2, 0xB3, 0xB0, 0xB5, 0xB6, 0xBF, 0xBC, 0xB9, 0xBA, 
-       0xFB, 0xF8, 0xFD, 0xFE, 0xF7, 0xF4, 0xF1, 0xF2, 0xE3, 0xE0, 0xE5, 0xE6, 0xEF, 0xEC, 0xE9, 0xEA, 
-       0xCB, 0xC8, 0xCD, 0xCE, 0xC7, 0xC4, 0xC1, 0xC2, 0xD3, 0xD0, 0xD5, 0xD6, 0xDF, 0xDC, 0xD9, 0xDA, 
-       0x5B, 0x58, 0x5D, 0x5E, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4F, 0x4C, 0x49, 0x4A, 
-       0x6B, 0x68, 0x6D, 0x6E, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7F, 0x7C, 0x79, 0x7A, 
-       0x3B, 0x38, 0x3D, 0x3E, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2F, 0x2C, 0x29, 0x2A, 
-       0x0B, 0x08, 0x0D, 0x0E, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1F, 0x1C, 0x19, 0x1A 
-       };
-
-       static byte[] multE = {
-       0x00, 0x0E, 0x1C, 0x12, 0x38, 0x36, 0x24, 0x2A, 0x70, 0x7E, 0x6C, 0x62, 0x48, 0x46, 0x54, 0x5A, 
-       0xE0, 0xEE, 0xFC, 0xF2, 0xD8, 0xD6, 0xC4, 0xCA, 0x90, 0x9E, 0x8C, 0x82, 0xA8, 0xA6, 0xB4, 0xBA, 
-       0xDB, 0xD5, 0xC7, 0xC9, 0xE3, 0xED, 0xFF, 0xF1, 0xAB, 0xA5, 0xB7, 0xB9, 0x93, 0x9D, 0x8F, 0x81, 
-       0x3B, 0x35, 0x27, 0x29, 0x03, 0x0D, 0x1F, 0x11, 0x4B, 0x45, 0x57, 0x59, 0x73, 0x7D, 0x6F, 0x61, 
-       0xAD, 0xA3, 0xB1, 0xBF, 0x95, 0x9B, 0x89, 0x87, 0xDD, 0xD3, 0xC1, 0xCF, 0xE5, 0xEB, 0xF9, 0xF7, 
-       0x4D, 0x43, 0x51, 0x5F, 0x75, 0x7B, 0x69, 0x67, 0x3D, 0x33, 0x21, 0x2F, 0x05, 0x0B, 0x19, 0x17, 
-       0x76, 0x78, 0x6A, 0x64, 0x4E, 0x40, 0x52, 0x5C, 0x06, 0x08, 0x1A, 0x14, 0x3E, 0x30, 0x22, 0x2C, 
-       0x96, 0x98, 0x8A, 0x84, 0xAE, 0xA0, 0xB2, 0xBC, 0xE6, 0xE8, 0xFA, 0xF4, 0xDE, 0xD0, 0xC2, 0xCC, 
-       0x41, 0x4F, 0x5D, 0x53, 0x79, 0x77, 0x65, 0x6B, 0x31, 0x3F, 0x2D, 0x23, 0x09, 0x07, 0x15, 0x1B, 
-       0xA1, 0xAF, 0xBD, 0xB3, 0x99, 0x97, 0x85, 0x8B, 0xD1, 0xDF, 0xCD, 0xC3, 0xE9, 0xE7, 0xF5, 0xFB, 
-       0x9A, 0x94, 0x86, 0x88, 0xA2, 0xAC, 0xBE, 0xB0, 0xEA, 0xE4, 0xF6, 0xF8, 0xD2, 0xDC, 0xCE, 0xC0, 
-       0x7A, 0x74, 0x66, 0x68, 0x42, 0x4C, 0x5E, 0x50, 0x0A, 0x04, 0x16, 0x18, 0x32, 0x3C, 0x2E, 0x20, 
-       0xEC, 0xE2, 0xF0, 0xFE, 0xD4, 0xDA, 0xC8, 0xC6, 0x9C, 0x92, 0x80, 0x8E, 0xA4, 0xAA, 0xB8, 0xB6, 
-       0x0C, 0x02, 0x10, 0x1E, 0x34, 0x3A, 0x28, 0x26, 0x7C, 0x72, 0x60, 0x6E, 0x44, 0x4A, 0x58, 0x56, 
-       0x37, 0x39, 0x2B, 0x25, 0x0F, 0x01, 0x13, 0x1D, 0x47, 0x49, 0x5B, 0x55, 0x7F, 0x71, 0x63, 0x6D, 
-       0xD7, 0xD9, 0xCB, 0xC5, 0xEF, 0xE1, 0xF3, 0xFD, 0xA7, 0xA9, 0xBB, 0xB5, 0x9F, 0x91, 0x83, 0x8D, 
-       };
-
-       static byte[] multB = {
-       0x00, 0x0B, 0x16, 0x1D, 0x2C, 0x27, 0x3A, 0x31, 0x58, 0x53, 0x4E, 0x45, 0x74, 0x7F, 0x62, 0x69, 
-       0xB0, 0xBB, 0xA6, 0xAD, 0x9C, 0x97, 0x8A, 0x81, 0xE8, 0xE3, 0xFE, 0xF5, 0xC4, 0xCF, 0xD2, 0xD9, 
-       0x7B, 0x70, 0x6D, 0x66, 0x57, 0x5C, 0x41, 0x4A, 0x23, 0x28, 0x35, 0x3E, 0x0F, 0x04, 0x19, 0x12, 
-       0xCB, 0xC0, 0xDD, 0xD6, 0xE7, 0xEC, 0xF1, 0xFA, 0x93, 0x98, 0x85, 0x8E, 0xBF, 0xB4, 0xA9, 0xA2, 
-       0xF6, 0xFD, 0xE0, 0xEB, 0xDA, 0xD1, 0xCC, 0xC7, 0xAE, 0xA5, 0xB8, 0xB3, 0x82, 0x89, 0x94, 0x9F, 
-       0x46, 0x4D, 0x50, 0x5B, 0x6A, 0x61, 0x7C, 0x77, 0x1E, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2F, 
-       0x8D, 0x86, 0x9B, 0x90, 0xA1, 0xAA, 0xB7, 0xBC, 0xD5, 0xDE, 0xC3, 0xC8, 0xF9, 0xF2, 0xEF, 0xE4, 
-       0x3D, 0x36, 0x2B, 0x20, 0x11, 0x1A, 0x07, 0x0C, 0x65, 0x6E, 0x73, 0x78, 0x49, 0x42, 0x5F, 0x54, 
-       0xF7, 0xFC, 0xE1, 0xEA, 0xDB, 0xD0, 0xCD, 0xC6, 0xAF, 0xA4, 0xB9, 0xB2, 0x83, 0x88, 0x95, 0x9E, 
-       0x47, 0x4C, 0x51, 0x5A, 0x6B, 0x60, 0x7D, 0x76, 0x1F, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2E, 
-       0x8C, 0x87, 0x9A, 0x91, 0xA0, 0xAB, 0xB6, 0xBD, 0xD4, 0xDF, 0xC2, 0xC9, 0xF8, 0xF3, 0xEE, 0xE5, 
-       0x3C, 0x37, 0x2A, 0x21, 0x10, 0x1B, 0x06, 0x0D, 0x64, 0x6F, 0x72, 0x79, 0x48, 0x43, 0x5E, 0x55, 
-       0x01, 0x0A, 0x17, 0x1C, 0x2D, 0x26, 0x3B, 0x30, 0x59, 0x52, 0x4F, 0x44, 0x75, 0x7E, 0x63, 0x68, 
-       0xB1, 0xBA, 0xA7, 0xAC, 0x9D, 0x96, 0x8B, 0x80, 0xE9, 0xE2, 0xFF, 0xF4, 0xC5, 0xCE, 0xD3, 0xD8, 
-       0x7A, 0x71, 0x6C, 0x67, 0x56, 0x5D, 0x40, 0x4B, 0x22, 0x29, 0x34, 0x3F, 0x0E, 0x05, 0x18, 0x13, 
-       0xCA, 0xC1, 0xDC, 0xD7, 0xE6, 0xED, 0xF0, 0xFB, 0x92, 0x99, 0x84, 0x8F, 0xBE, 0xB5, 0xA8, 0xA3, 
-       };
-
-       static byte[] multD = {
-       0x00, 0x0D, 0x1A, 0x17, 0x34, 0x39, 0x2E, 0x23, 0x68, 0x65, 0x72, 0x7F, 0x5C, 0x51, 0x46, 0x4B, 
-       0xD0, 0xDD, 0xCA, 0xC7, 0xE4, 0xE9, 0xFE, 0xF3, 0xB8, 0xB5, 0xA2, 0xAF, 0x8C, 0x81, 0x96, 0x9B, 
-       0xBB, 0xB6, 0xA1, 0xAC, 0x8F, 0x82, 0x95, 0x98, 0xD3, 0xDE, 0xC9, 0xC4, 0xE7, 0xEA, 0xFD, 0xF0, 
-       0x6B, 0x66, 0x71, 0x7C, 0x5F, 0x52, 0x45, 0x48, 0x03, 0x0E, 0x19, 0x14, 0x37, 0x3A, 0x2D, 0x20, 
-       0x6D, 0x60, 0x77, 0x7A, 0x59, 0x54, 0x43, 0x4E, 0x05, 0x08, 0x1F, 0x12, 0x31, 0x3C, 0x2B, 0x26, 
-       0xBD, 0xB0, 0xA7, 0xAA, 0x89, 0x84, 0x93, 0x9E, 0xD5, 0xD8, 0xCF, 0xC2, 0xE1, 0xEC, 0xFB, 0xF6, 
-       0xD6, 0xDB, 0xCC, 0xC1, 0xE2, 0xEF, 0xF8, 0xF5, 0xBE, 0xB3, 0xA4, 0xA9, 0x8A, 0x87, 0x90, 0x9D, 
-       0x06, 0x0B, 0x1C, 0x11, 0x32, 0x3F, 0x28, 0x25, 0x6E, 0x63, 0x74, 0x79, 0x5A, 0x57, 0x40, 0x4D, 
-       0xDA, 0xD7, 0xC0, 0xCD, 0xEE, 0xE3, 0xF4, 0xF9, 0xB2, 0xBF, 0xA8, 0xA5, 0x86, 0x8B, 0x9C, 0x91, 
-       0x0A, 0x07, 0x10, 0x1D, 0x3E, 0x33, 0x24, 0x29, 0x62, 0x6F, 0x78, 0x75, 0x56, 0x5B, 0x4C, 0x41, 
-       0x61, 0x6C, 0x7B, 0x76, 0x55, 0x58, 0x4F, 0x42, 0x09, 0x04, 0x13, 0x1E, 0x3D, 0x30, 0x27, 0x2A, 
-       0xB1, 0xBC, 0xAB, 0xA6, 0x85, 0x88, 0x9F, 0x92, 0xD9, 0xD4, 0xC3, 0xCE, 0xED, 0xE0, 0xF7, 0xFA, 
-       0xB7, 0xBA, 0xAD, 0xA0, 0x83, 0x8E, 0x99, 0x94, 0xDF, 0xD2, 0xC5, 0xC8, 0xEB, 0xE6, 0xF1, 0xFC, 
-       0x67, 0x6A, 0x7D, 0x70, 0x53, 0x5E, 0x49, 0x44, 0x0F, 0x02, 0x15, 0x18, 0x3B, 0x36, 0x21, 0x2C, 
-       0x0C, 0x01, 0x16, 0x1B, 0x38, 0x35, 0x22, 0x2F, 0x64, 0x69, 0x7E, 0x73, 0x50, 0x5D, 0x4A, 0x47, 
-       0xDC, 0xD1, 0xC6, 0xCB, 0xE8, 0xE5, 0xF2, 0xFF, 0xB4, 0xB9, 0xAE, 0xA3, 0x80, 0x8D, 0x9A, 0x97, 
-       };
-
-       static byte[] mult9 = {
-       0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F, 0x48, 0x41, 0x5A, 0x53, 0x6C, 0x65, 0x7E, 0x77, 
-       0x90, 0x99, 0x82, 0x8B, 0xB4, 0xBD, 0xA6, 0xAF, 0xD8, 0xD1, 0xCA, 0xC3, 0xFC, 0xF5, 0xEE, 0xE7, 
-       0x3B, 0x32, 0x29, 0x20, 0x1F, 0x16, 0x0D, 0x04, 0x73, 0x7A, 0x61, 0x68, 0x57, 0x5E, 0x45, 0x4C, 
-       0xAB, 0xA2, 0xB9, 0xB0, 0x8F, 0x86, 0x9D, 0x94, 0xE3, 0xEA, 0xF1, 0xF8, 0xC7, 0xCE, 0xD5, 0xDC, 
-       0x76, 0x7F, 0x64, 0x6D, 0x52, 0x5B, 0x40, 0x49, 0x3E, 0x37, 0x2C, 0x25, 0x1A, 0x13, 0x08, 0x01, 
-       0xE6, 0xEF, 0xF4, 0xFD, 0xC2, 0xCB, 0xD0, 0xD9, 0xAE, 0xA7, 0xBC, 0xB5, 0x8A, 0x83, 0x98, 0x91, 
-       0x4D, 0x44, 0x5F, 0x56, 0x69, 0x60, 0x7B, 0x72, 0x05, 0x0C, 0x17, 0x1E, 0x21, 0x28, 0x33, 0x3A, 
-       0xDD, 0xD4, 0xCF, 0xC6, 0xF9, 0xF0, 0xEB, 0xE2, 0x95, 0x9C, 0x87, 0x8E, 0xB1, 0xB8, 0xA3, 0xAA, 
-       0xEC, 0xE5, 0xFE, 0xF7, 0xC8, 0xC1, 0xDA, 0xD3, 0xA4, 0xAD, 0xB6, 0xBF, 0x80, 0x89, 0x92, 0x9B, 
-       0x7C, 0x75, 0x6E, 0x67, 0x58, 0x51, 0x4A, 0x43, 0x34, 0x3D, 0x26, 0x2F, 0x10, 0x19, 0x02, 0x0B, 
-       0xD7, 0xDE, 0xC5, 0xCC, 0xF3, 0xFA, 0xE1, 0xE8, 0x9F, 0x96, 0x8D, 0x84, 0xBB, 0xB2, 0xA9, 0xA0, 
-       0x47, 0x4E, 0x55, 0x5C, 0x63, 0x6A, 0x71, 0x78, 0x0F, 0x06, 0x1D, 0x14, 0x2B, 0x22, 0x39, 0x30, 
-       0x9A, 0x93, 0x88, 0x81, 0xBE, 0xB7, 0xAC, 0xA5, 0xD2, 0xDB, 0xC0, 0xC9, 0xF6, 0xFF, 0xE4, 0xED, 
-       0x0A, 0x03, 0x18, 0x11, 0x2E, 0x27, 0x3C, 0x35, 0x42, 0x4B, 0x50, 0x59, 0x66, 0x6F, 0x74, 0x7D, 
-       0xA1, 0xA8, 0xB3, 0xBA, 0x85, 0x8C, 0x97, 0x9E, 0xE9, 0xE0, 0xFB, 0xF2, 0xCD, 0xC4, 0xDF, 0xD6, 
-       0x31, 0x38, 0x23, 0x2A, 0x15, 0x1C, 0x07, 0x0E, 0x79, 0x70, 0x6B, 0x62, 0x5D, 0x54, 0x4F, 0x46, 
-       };
-
-}
-
 }
-
index 69ee3f063a019654b741220218686c480c505f67..f74c86f1350c9262274ae0f095aab58a1b53b71d 100644 (file)
 //
 
 using System;
+using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography {
 
-// References:
-// a.  FIPS PUB 46-3: TripleDES
-//     http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
-// b.  ANSI X9.52
-//     not free :-(
-//     http://webstore.ansi.org/ansidocstore/product.asp?sku=ANSI+X9%2E52%2D1998
-
-public sealed class TripleDESCryptoServiceProvider : TripleDES {
-
-       public TripleDESCryptoServiceProvider () {}
-
-       public override void GenerateIV () 
-       {
-               IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
-       }
-       
-       public override void GenerateKey () 
-       {
-               KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
-       }
+       // References:
+       // a.   FIPS PUB 46-3: TripleDES
+       //      http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
+       // b.   ANSI X9.52
+       //      not free :-(
+       //      http://webstore.ansi.org/ansidocstore/product.asp?sku=ANSI+X9%2E52%2D1998
        
-       public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) 
-       {
-               Key = rgbKey;
-               IV = rgbIV;
-               return new TripleDESTransform (this, false, rgbKey, rgbIV);
-       }
+       public sealed class TripleDESCryptoServiceProvider : TripleDES {
        
-       public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) 
-       {
-               Key = rgbKey;
-               IV = rgbIV;
-               return new TripleDESTransform (this, true, rgbKey, rgbIV);
-       }
-}
-
-// TripleDES is just DES-EDE
-internal class TripleDESTransform : SymmetricTransform {
-
-       // for encryption
-       private DESTransform E1;
-       private DESTransform D2;
-       private DESTransform E3;
-
-       // for decryption
-       private DESTransform D1;
-       private DESTransform E2;
-       private DESTransform D3;
+               public TripleDESCryptoServiceProvider () {}
        
-       public TripleDESTransform (TripleDES algo, bool encryption, byte[] key, byte[] iv) : base (algo, encryption, iv) 
-       {
-               byte[] key1 = new byte [8];
-               byte[] key2 = new byte [8];
-               byte[] key3 = new byte [8];
-               DES des = DES.Create ();
-               Array.Copy (key, 0, key1, 0, 8);
-               Array.Copy (key, 8, key2, 0, 8);
-               if (key.Length == 16)
-                       Array.Copy (key, 0, key3, 0, 8);
-               else
-                       Array.Copy (key, 16, key3, 0, 8);
-
-               // note: some modes (like CFB) requires encryption when decrypting
-               if ((encryption) || (algo.Mode == CipherMode.CFB)) {
-                       E1 = new DESTransform (des, true, key1, iv);
-                       D2 = new DESTransform (des, false, key2, iv);
-                       E3 = new DESTransform (des, true, key3, iv);
+               public override void GenerateIV () 
+               {
+                       IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
+               }
+               
+               public override void GenerateKey () 
+               {
+                       KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
+               }
+               
+               public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) 
+               {
+                       Key = rgbKey;
+                       IV = rgbIV;
+                       return new TripleDESTransform (this, false, rgbKey, rgbIV);
                }
-               else {
-                       D1 = new DESTransform (des, false, key3, iv);
-                       E2 = new DESTransform (des, true, key2, iv);
-                       D3 = new DESTransform (des, false, key1, iv);
+               
+               public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) 
+               {
+                       Key = rgbKey;
+                       IV = rgbIV;
+                       return new TripleDESTransform (this, true, rgbKey, rgbIV);
                }
        }
-
-       // note: this method is garanteed to be called with a valid blocksize
-       // for both input and output
-       protected override void ECB (byte[] input, byte[] output) 
-       {
-               byte[] temp = new byte [input.Length];
-               if (encrypt) {
-                       E1.ProcessBlock (input, output);
-                       D2.ProcessBlock (output, temp);
-                       E3.ProcessBlock (temp, output);
+       
+       // TripleDES is just DES-EDE
+       internal class TripleDESTransform : SymmetricTransform {
+       
+               // for encryption
+               private DESTransform E1;
+               private DESTransform D2;
+               private DESTransform E3;
+       
+               // for decryption
+               private DESTransform D1;
+               private DESTransform E2;
+               private DESTransform D3;
+               
+               public TripleDESTransform (TripleDES algo, bool encryption, byte[] key, byte[] iv) : base (algo, encryption, iv) 
+               {
+                       byte[] key1 = new byte [8];
+                       byte[] key2 = new byte [8];
+                       byte[] key3 = new byte [8];
+                       DES des = DES.Create ();
+                       Array.Copy (key, 0, key1, 0, 8);
+                       Array.Copy (key, 8, key2, 0, 8);
+                       if (key.Length == 16)
+                               Array.Copy (key, 0, key3, 0, 8);
+                       else
+                               Array.Copy (key, 16, key3, 0, 8);
+       
+                       // note: some modes (like CFB) requires encryption when decrypting
+                       if ((encryption) || (algo.Mode == CipherMode.CFB)) {
+                               E1 = new DESTransform (des, true, key1, iv);
+                               D2 = new DESTransform (des, false, key2, iv);
+                               E3 = new DESTransform (des, true, key3, iv);
+                       }
+                       else {
+                               D1 = new DESTransform (des, false, key3, iv);
+                               E2 = new DESTransform (des, true, key2, iv);
+                               D3 = new DESTransform (des, false, key1, iv);
+                       }
                }
-               else {
-                       D1.ProcessBlock (input, output);
-                       E2.ProcessBlock (output, temp);
-                       D3.ProcessBlock (temp, output);
+       
+               // note: this method is garanteed to be called with a valid blocksize
+               // for both input and output
+               protected override void ECB (byte[] input, byte[] output) 
+               {
+                       byte[] temp = new byte [input.Length];
+                       if (encrypt) {
+                               E1.ProcessBlock (input, output);
+                               D2.ProcessBlock (output, temp);
+                               E3.ProcessBlock (temp, output);
+                       }
+                       else {
+                               D1.ProcessBlock (input, output);
+                               E2.ProcessBlock (output, temp);
+                               D3.ProcessBlock (temp, output);
+                       }
                }
        }
 }
-
-}