-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
// 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
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;
}
}
-
-}
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
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
//
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);
- }
-}
-
}
//
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
- };
-}
-
}
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;
}
}
-
-}
//
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 ();
}
}
-
-}
//
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 ();
}
}
-
-}
//
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 ();
}
}
-
-}
//
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!
}
}
-
-}
//
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);
- }
-}
-
}
//
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!
}
}
-
-}
//
using System;
+using Mono.Security.Cryptography;
/// <summary>
/// Rijndael is a symmetric block cipher supporting block and key sizes
/// </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,
- };
-
-}
-
}
-
//
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);
+ }
}
}
}
-
-}