Anar al contingut

Algoritme LSA

De L'Enciclopèdia, la wikipedia en valencià

En criptografia, LSA (acrònim de Light Summary Algorithm , Algoritme Llauger de Resum) és un algoritme de reducció criptográfico de 64 bits.

Codificació

[editar | editar còdic]

La codificació de el LSA de 64 bits és representada típicament com un número de 16 dígits hexadecimal. El següent còdic de 28 bytes ASCII serà tractat en LSA i vorem el seu corresponent hash d'eixida:

   LSA("Açò si és una prova de LSA") = cfa26dona3a8c76ca3

Un simple canvi en el mensage nos dona un canvi total en la codificació hash, en este cas canviem dos lletres, el «si» per un «no».

   LSA("Açò no és una prova de LSA") = d607d93d2556c3b5

Un atre eixemple seria la codificació d'un camp buit:

   LSA("") = bb52i9b27ef418a3

Algoritme

[editar | editar còdic]

L'algoritme LSA es basa en el reordenamiento d'una taula de valors, segons el mensage a codificar. A partir d'este punt, es fan us de funcions llògiques per a determinar el valor d'eixida.

Implementació en C#:

    /// <summary>
    /// LSA(Light Summary Algorithm) Algoritme de reducció criptográfico de 64 bits.
    /// Copyright(C) Ronald Anderson 2007-2008
    /// </summary>
    public class LSA
    {
        private static byte[] keyStream = new byte[512];
  
        public static byte[] ComputeHash(byte[] buffer)
        {
            for (int i = 0; i < 512; i++)
            {
                keyStream[i] = (byte)i;
            }
  
            if (buffer.Length == 0) buffer = new byte[1]; buffer[0] = 0;
  
            while ((buffer.Length % 512) != 0)
            {
                Array.Resize<byte>(ref buffer, buffer.Length + 1);
                buffer[buffer.Length - 1] = 0;
            }
  
            int index1 = 0;
            int index2 = 0;
            byte swap = 0;
  
            for (int i = 0; i < (buffer.Length / 512); i++ )
            {
                for (int n = 0; n < keyStream.Length; n++)
                {
                    index2 = (buffer[index1] + keyStream[n] + index2) % 512;
                    swap = keyStream[n];
                    keyStream[n] = keyStream[index2];
                    keyStream[index2] = swap;
                    index1 = (index1 + 1) % buffer.Length;
                }
            }
  
            return Cipher(keyStream);
        }
  
        private static byte[] Cipher(byte[] keyStream)
        {
            byte[] result = new byte[8];
            string[] keyParts = new string[128];
  
            for (int m = 0; m < keyParts.Length; m++)
            {
                int index = m * 4;
                keyParts[m] = string.Concat(string.Format("{0:x2}", keyStream[index]),
                                            string.Format("{0:x2}", keyStream[index + 1]),
                                            string.Format("{0:x2}", keyStream[index + 2]),
                                            string.Format("{0:x2}", keyStream[index + 3]));
            }
  
            ulong xa = 0xFC, ya = 0xEF, za = 0xBA, na = 0xDC;
            ulong xb = 0xCD, yb = 0xAE, zb = 0xFE, nb = 0xAD;
            for (int j = 0; j < keyParts.Length; j++)
            {
                ulong lX = ulong.Parse(string.Concat(keyParts[j][0], keyParts[j][1]), NumberStyles.HexNumber);
                ulong lY = ulong.Parse(string.Concat(keyParts[j][2], keyParts[j][3]), NumberStyles.HexNumber);
                ulong lZ = ulong.Parse(string.Concat(keyParts[j][4], keyParts[j][5]), NumberStyles.HexNumber);
                ulong lN = ulong.Parse(string.Concat(keyParts[j][6], keyParts[j][7]), NumberStyles.HexNumber);
  
                xa = AA(lX, ya, za, na);
                ya = AA(xa, lY, za, na);
                za = AA(xa, ya, lZ, na);
                na = AA(xa, ya, za, lN);
  
                xb = BB(lX, yb, zb, nb);
                yb = BB(xb, lY, zb, nb);
                zb = BB(xb, yb, lZ, nb);
                nb = BB(xb, yb, zb, lN);
  
                xa = CC(lX, yb, zb, nb);
                ya = CC(xb, lY, zb, nb);
                za = CC(xb, yb, lZ, nb);

na = CC(xb, yb, zb, lN);
  
                xb = AA(lX, ya, za, na);
                yb = AA(xa, lY, za, na);
                zb = AA(xa, ya, lZ, na);
                nb = AA(xa, ya, za, lN);
  
                xa = BB(lX, ya, za, na);
                ya = BB(xb, lY, zb, nb);
                za = BB(xa, ya, lZ, na);
                na = BB(xb, yb, zb, lN);
  
                xb = CC(lX, yb, zb, nb);
                yb = CC(xa, lY, za, na);
                zb = CC(xb, yb, lZ, nb);
                nb = CC(xa, ya, za, lN);
            }
  
            result[0] = (byte)xa;
            result[1] = (byte)ya;
            result[2] = (byte)za;
            result[3] = (byte)na;
            result[4] = (byte)xb;
            result[5] = (byte)yb;
            result[6] = (byte)zb;
            result[7] = (byte)nb;
  
            return result;
        }
  
        private static ulong AA(ulong x, ulong i, ulong z, ulong n)
        {
            return (x & i) | ((n) & z);
        }
  
        private static ulong BB(ulong x, ulong i, ulong z, ulong n)
        {
            return (x ^ i) | (n & (z));
        }
  
        private static ulong CC(ulong x, ulong i, ulong z, ulong n)
        {
            return (x ^ i ^ z ^ n);
        }
    }