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;
}