Пример #1
0
 public static byte[] WithHeader(byte[] message)
 {
     byte[] nmsg = new byte[message.Length + 4];
     Support.WriteToArray(nmsg, message.Length, 0);
     Array.Copy(message, 0, nmsg, 4, message.Length);
     return(nmsg);
 }
Пример #2
0
        // Password-Based Key Derivation Function 2. Used to generate "pseudorandom" keys from a given password and salt using a certain PRF applied a certain amount of times (iterations).
        // dklen specified the "derived key length" in bytes. It is recommended to use a high number for the iterations variable (somewhere around 4096 is the standard for SHA1 currently)
        public static byte[] PBKDF2(PRF function, byte[] password, byte[] salt, int iterations, int dklen)
        {
            byte[] dk   = new byte[0]; // Create a placeholder for the derived key
            uint   iter = 1;           // Track the iterations

            while (dk.Length < dklen)
            {
                // F-function
                // The F-function (PRF) takes the amount of iterations performed in the opposite endianness format from what C# uses, so we have to swap the endianness
                byte[] u    = function(password, Support.Concatenate(salt, Support.WriteToArray(new byte[4], Support.SwapEndian(iter), 0)));
                byte[] ures = new byte[u.Length];
                Array.Copy(u, ures, u.Length);
                for (int i = 1; i < iterations; ++i)
                {
                    // Iteratively apply the PRF
                    u = function(password, u);
                    for (int j = 0; j < u.Length; ++j)
                    {
                        ures[j] ^= u[j];
                    }
                }

                // Concatenate the result to the dk
                dk = Support.Concatenate(dk, ures);

                ++iter;
            }

            // Clip aby bytes past what we needed (yes, that's really what the standard is)
            return(dk.ToLength(dklen));
        }
Пример #3
0
 // Internal methods for encryption :)
 private static uint KSchedCore(uint input, int iteration)
 {
     input = Rotate(input);
     byte[] bytes = Support.WriteToArray(new byte[4], input, 0);
     for (int i = 0; i < bytes.Length; ++i)
     {
         bytes[i] = SBox(bytes[i]);
     }
     bytes[bytes.Length - 1] ^= RCON(iteration);
     return((uint)Support.ReadInt(bytes, 0));
 }
Пример #4
0
        private static byte[] KeySchedule(byte[] key, BitMode mode)
        {
            int n = mode == BitMode.Bit128 ? 16 : mode == BitMode.Bit192 ? 24 : 32;
            int b = mode == BitMode.Bit128 ? 176 : mode == BitMode.Bit192 ? 208 : 240;

            byte[] output = new byte[b];
            Array.Copy(key, output, n);

            int rcon_iter = 1;

            int accruedBytes = n;

            while (accruedBytes < b)
            {
                // Generate 4 new bytes of extended key
                byte[] t = Support.WriteToArray(new byte[4], KSchedCore((uint)Support.ReadInt(output, accruedBytes - 4), rcon_iter), 0);
                ++rcon_iter;
                for (int i = 0; i < 4; ++i)
                {
                    t[i] ^= output[accruedBytes - n + i];
                }
                Array.Copy(t, 0, output, accruedBytes, 4);
                accruedBytes += 4;

                // Generate 12 new bytes of extended key
                for (int i = 0; i < 3; ++i)
                {
                    Array.Copy(output, accruedBytes - 4, t, 0, 4);
                    for (int j = 0; j < 4; ++j)
                    {
                        t[j] ^= output[accruedBytes - n + j];
                    }
                    Array.Copy(t, 0, output, accruedBytes, 4);
                    accruedBytes += 4;
                }

                // Special processing for 256-bit key schedule
                if (mode == BitMode.Bit256)
                {
                    Array.Copy(output, accruedBytes - 4, t, 0, 4);
                    for (int j = 0; j < 4; ++j)
                    {
                        t[j] = (byte)(SBox(t[j]) ^ output[accruedBytes - n + j]);
                    }
                    Array.Copy(t, 0, output, accruedBytes, 4);
                    accruedBytes += 4;
                }
                // Special processing for 192-bit key schedule
                if (mode != BitMode.Bit128)
                {
                    for (int i = mode == BitMode.Bit192 ? 1 : 2; i >= 0; --i)
                    {
                        Array.Copy(output, accruedBytes - 4, t, 0, 4);
                        for (int j = 0; j < 4; ++j)
                        {
                            t[j] ^= output[accruedBytes - n + j];
                        }
                        Array.Copy(t, 0, output, accruedBytes, 4);
                        accruedBytes += 4;
                    }
                }
            }

            return(output);
        }