private static int w = 32, r = 20; private static readonly double e = Math.E; private const double goldenRatio = 1.6180339887496482; private static int Pw = unchecked((int)0xb7e15163), Qw = unchecked((int)0x9e3779b9); private static int[] S; private static int[] convBytesWords(sbyte[] key, int u, int c) { int[] tmp = new int[c]; for (int i = 0; i < tmp.Length; i++) { tmp[i] = 0; } for (int i = 0, off = 0; i < c; i++) { tmp[i] = ((key[off++] & 0xFF)) | ((key[off++] & 0xFF) << 8) | ((key[off++] & 0xFF) << 16) | ((key[off++] & 0xFF) << 24); } return tmp; } private static int[] generateSubkeys(sbyte[] key) { int u = w / 8; int c = key.Length / u; int t = 2 * r + 4; int[] L = convBytesWords(key, u, c); int[] S = new int[t]; S[0] = Pw; for (int i = 1; i < t; i++) { S[i] = S[i - 1] + Qw; } int A = 0; int B = 0; int k = 0, j = 0; int v = 3 * Math.Max(c, t); for (int i = 0; i < v; i++) { A = S[k] = rotl((S[k] + A + B), 3); B = L[j] = rotl(L[j] + A + B, A + B); k = (k + 1) % t; j = (j + 1) % c; } return S; } private static sbyte[] decryptBloc(sbyte[] input) { sbyte[] tmp = new sbyte[input.Length]; int t, u; int aux; int[] data = new int[input.Length / 4]; for (int i = 0; i < data.Length; i++) { data[i] = 0; } int off = 0; for (int i = 0; i < data.Length; i++) { data[i] = ((input[off++] & 0xff)) | ((input[off++] & 0xff) << 8) | ((input[off++] & 0xff) << 16) | ((input[off++] & 0xff) << 24); } int A = data[0], B = data[1], C = data[2], D = data[3]; C = C - S[2 * r + 3]; A = A - S[2 * r + 2]; for (int i = r; i >= 1; i--) { aux = D; D = C; C = B; B = A; A = aux; u = rotl(D * (2 * D + 1), 5); t = rotl(B * (2 * B + 1), 5); C = rotr(C - S[2 * i + 1], t) ^ u; A = rotr(A - S[2 * i], u) ^ t; } D = D - S[1]; B = B - S[0]; data[0] = A; data[1] = B; data[2] = C; data[3] = D; for (int i = 0; i < tmp.Length; i++) { tmp[i] = unchecked((sbyte)(((int)((uint)data[i / 4] >> (i % 4) * 8)) & 0xff)); } return tmp; } private static sbyte[] encryptBloc(sbyte[] input) { sbyte[] tmp = new sbyte[input.Length]; int t, u; int aux; int[] data = new int[input.Length / 4]; for (int i = 0; i < data.Length; i++) { data[i] = 0; } int off = 0; for (int i = 0; i < data.Length; i++) { data[i] = ((input[off++] & 0xff)) | ((input[off++] & 0xff) << 8) | ((input[off++] & 0xff) << 16) | ((input[off++] & 0xff) << 24); } int A = data[0], B = data[1], C = data[2], D = data[3]; B = B + S[0]; D = D + S[1]; for (int i = 1; i <= r; i++) { t = rotl(B * (2 * B + 1), 5); u = rotl(D * (2 * D + 1), 5); A = rotl(A ^ t, u) + S[2 * i]; C = rotl(C ^ u, t) + S[2 * i + 1]; aux = A; A = B; B = C; C = D; D = aux; } A = A + S[2 * r + 2]; C = C + S[2 * r + 3]; data[0] = A; data[1] = B; data[2] = C; data[3] = D; for (int i = 0; i < tmp.Length; i++) { tmp[i] = unchecked((sbyte)(((int)((uint)data[i / 4] >> (i % 4) * 8)) & 0xff)); } return tmp; } private static sbyte[] paddingKey(sbyte[] key) { int l = key.Length % 4; for (int i = 0; i < l; i++) { key[key.Length + i] = 0; } return key; } [WebMethod] public sbyte[] encrypt(sbyte[] data, sbyte[] key) { sbyte[] bloc = new sbyte[16]; key = paddingKey(key); S = generateSubkeys(key); int lenght = 16 - data.Length % 16; sbyte[] padding = new sbyte[lenght]; padding[0] = unchecked((sbyte)0x80); for (int i = 1; i < lenght; i++) { padding[i] = 0; } int count = 0; sbyte[] tmp = new sbyte[data.Length + lenght]; //afiseazaMatrice(S); int j; for (j = 0; j < data.Length + lenght; j++) { if (j > 0 && j % 16 == 0) { bloc = encryptBloc(bloc); Array.Copy(bloc, 0, tmp, j - 16, bloc.Length); } if (j < data.Length) { bloc[j % 16] = data[j]; } else { bloc[j % 16] = padding[count]; count++; if (count > lenght - 1) { count = 1; } } } bloc = encryptBloc(bloc); Array.Copy(bloc, 0, tmp, j - 16, bloc.Length); return tmp; } public static sbyte[] decrypt(sbyte[] data, sbyte[] key) { sbyte[] tmp = new sbyte[data.Length]; sbyte[] bloc = new sbyte[16]; key = paddingKey(key); S = generateSubkeys(key); int i; for (i = 0; i < data.Length; i++) { if (i > 0 && i % 16 == 0) { bloc = decryptBloc(bloc); Array.Copy(bloc, 0, tmp, i - 16, bloc.Length); } if (i < data.Length) { bloc[i % 16] = data[i]; } } bloc = decryptBloc(bloc); Array.Copy(bloc, 0, tmp, i - 16, bloc.Length); tmp = deletePadding(tmp); return tmp; } private static sbyte[] deletePadding(sbyte[] input) { int count = 0; int i = input.Length - 1; while (input[i] == 0) { count++; i--; } sbyte[] tmp = new sbyte[input.Length - count - 1]; Array.Copy(input, 0, tmp, 0, tmp.Length); return tmp; }