Exemple #1
0
        private void ProcessWord(byte[] Input, int Offset)
        {
            m_wordBuffer[m_wordOffset] = IntUtils.BytesToBe32(Input, Offset);

            if (++m_wordOffset == 16)
            {
                ProcessBlock();
            }
        }
Exemple #2
0
 /// <remarks>
 /// Convert to big endian integers, increment and convert back
 /// </remarks>
 private void Rotate(byte[] Counter)
 {
     // rotate the counter at 32 or 64 bit intervals
     if (RotationalAlignment == CounterAlignmentSizes.RAP32)
     {
         for (int i = 0; i < Counter.Length; i += 4)
         {
             IntUtils.Be32ToBytes(IntUtils.BytesToBe32(Counter, i) + 1, Counter, i);
         }
     }
     else
     {
         for (int i = 0; i < Counter.Length; i += 8)
         {
             IntUtils.Be64ToBytes(IntUtils.BytesToBe64(Counter, i) + 1, Counter, i);
         }
     }
 }
Exemple #3
0
        private void Compress(byte[] Block, int Offset)
        {
            _M[0]  = IntUtils.BytesToBe32(Block, Offset);
            _M[1]  = IntUtils.BytesToBe32(Block, Offset + 4);
            _M[2]  = IntUtils.BytesToBe32(Block, Offset + 8);
            _M[3]  = IntUtils.BytesToBe32(Block, Offset + 12);
            _M[4]  = IntUtils.BytesToBe32(Block, Offset + 16);
            _M[5]  = IntUtils.BytesToBe32(Block, Offset + 20);
            _M[6]  = IntUtils.BytesToBe32(Block, Offset + 24);
            _M[7]  = IntUtils.BytesToBe32(Block, Offset + 28);
            _M[8]  = IntUtils.BytesToBe32(Block, Offset + 32);
            _M[9]  = IntUtils.BytesToBe32(Block, Offset + 36);
            _M[10] = IntUtils.BytesToBe32(Block, Offset + 40);
            _M[11] = IntUtils.BytesToBe32(Block, Offset + 44);
            _M[12] = IntUtils.BytesToBe32(Block, Offset + 48);
            _M[13] = IntUtils.BytesToBe32(Block, Offset + 52);
            _M[14] = IntUtils.BytesToBe32(Block, Offset + 56);
            _M[15] = IntUtils.BytesToBe32(Block, Offset + 60);

            _V[0]  = _hashVal[0];
            _V[1]  = _hashVal[1];
            _V[2]  = _hashVal[2];
            _V[3]  = _hashVal[3];
            _V[4]  = _hashVal[4];
            _V[5]  = _hashVal[5];
            _V[6]  = _hashVal[6];
            _V[7]  = _hashVal[7];
            _V[8]  = _salt32[0] ^ 0x243F6A88U;
            _V[9]  = _salt32[1] ^ 0x85A308D3U;
            _V[10] = _salt32[2] ^ 0x13198A2EU;
            _V[11] = _salt32[3] ^ 0x03707344U;
            _V[12] = 0xA4093822U;
            _V[13] = 0x299F31D0U;
            _V[14] = 0x082EFA98U;
            _V[15] = 0xEC4E6C89U;

            if (!_isNullT)
            {
                uint uLen = (uint)(_T & 0xFFFFFFFFU);
                _V[12] ^= uLen;
                _V[13] ^= uLen;
                uLen    = (uint)((_T >> 32) & 0xFFFFFFFFU);
                _V[14] ^= uLen;
                _V[15] ^= uLen;
            }

            uint index = 0;

            do
            {
                MixBlock(index);
                index++;
            } while (index != ROUNDS);

            _hashVal[0] ^= _V[0];
            _hashVal[1] ^= _V[1];
            _hashVal[2] ^= _V[2];
            _hashVal[3] ^= _V[3];
            _hashVal[4] ^= _V[4];
            _hashVal[5] ^= _V[5];
            _hashVal[6] ^= _V[6];
            _hashVal[7] ^= _V[7];
            _hashVal[0] ^= _V[8];
            _hashVal[1] ^= _V[9];
            _hashVal[2] ^= _V[10];
            _hashVal[3] ^= _V[11];
            _hashVal[4] ^= _V[12];
            _hashVal[5] ^= _V[13];
            _hashVal[6] ^= _V[14];
            _hashVal[7] ^= _V[15];
            _hashVal[0] ^= _salt32[0];
            _hashVal[1] ^= _salt32[1];
            _hashVal[2] ^= _salt32[2];
            _hashVal[3] ^= _salt32[3];
            _hashVal[4] ^= _salt32[0];
            _hashVal[5] ^= _salt32[1];
            _hashVal[6] ^= _salt32[2];
            _hashVal[7] ^= _salt32[3];
        }
Exemple #4
0
        private uint[] StandardExpand(byte[] Key)
        {
            int cnt     = 0;
            int index   = 0;
            int padSize = Key.Length < 32 ? 16 : Key.Length / 2;

            uint[] tmpKey = new uint[padSize];
            int    offset = 0;

            // CHANGE: 512 key gets 8 extra rounds
            m_rndCount = (Key.Length == 64) ? 40 : ROUNDS32;
            int keySize = 4 * (m_rndCount + 1);

            // step 1: reverse copy key to temp array
            for (offset = Key.Length; offset > 0; offset -= 4)
            {
                tmpKey[index++] = IntUtils.BytesToBe32(Key, offset - 4);
            }

            // pad small key
            if (index < 8)
            {
                tmpKey[index] = 1;
            }

            // initialize the key
            uint[] expKey = new uint[keySize];

            if (padSize == 16)
            {
                // 32 byte key
                // step 2: rotate k into w(k) ints
                for (int i = 8; i < 16; i++)
                {
                    tmpKey[i] = IntUtils.RotateLeft((uint)(tmpKey[i - 8] ^ tmpKey[i - 5] ^ tmpKey[i - 3] ^ tmpKey[i - 1] ^ PHI ^ (i - 8)), 11);
                }

                // copy to expanded key
                Array.Copy(tmpKey, 8, expKey, 0, 8);

                // step 3: calculate remainder of rounds with rotating primitive
                for (int i = 8; i < keySize; i++)
                {
                    expKey[i] = IntUtils.RotateLeft((uint)(expKey[i - 8] ^ expKey[i - 5] ^ expKey[i - 3] ^ expKey[i - 1] ^ PHI ^ i), 11);
                }
            }
            else
            {
                // *extended*: 64 byte key
                // step 3: rotate k into w(k) ints, with extended polynominal
                // Wp := (Wp-16 ^ Wp-13 ^ Wp-11 ^ Wp-10 ^ Wp-8 ^ Wp-5 ^ Wp-3 ^ Wp-1 ^ PHI ^ i) <<< 11
                for (int i = 16; i < 32; i++)
                {
                    tmpKey[i] = IntUtils.RotateLeft((uint)(tmpKey[i - 16] ^ tmpKey[i - 13] ^ tmpKey[i - 11] ^ tmpKey[i - 10] ^ tmpKey[i - 8] ^ tmpKey[i - 5] ^ tmpKey[i - 3] ^ tmpKey[i - 1] ^ PHI ^ (i - 16)), 11);
                }

                // copy to expanded key
                Array.Copy(tmpKey, 16, expKey, 0, 16);

                // step 3: calculate remainder of rounds with rotating primitive
                for (int i = 16; i < keySize; i++)
                {
                    expKey[i] = IntUtils.RotateLeft((uint)(expKey[i - 16] ^ expKey[i - 13] ^ expKey[i - 11] ^ expKey[i - 10] ^ expKey[i - 8] ^ expKey[i - 5] ^ expKey[i - 3] ^ expKey[i - 1] ^ PHI ^ i), 11);
                }
            }

            // step 4: create the working keys by processing with the Sbox and IP
            while (cnt < keySize - 4)
            {
                Sb3(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4;
                Sb2(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4;
                Sb1(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4;
                Sb0(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4;
                Sb7(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4;
                Sb6(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4;
                Sb5(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4;
                Sb4(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4;
            }

            // last round
            Sb3(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]);

            return(expKey);
        }
Exemple #5
0
        private void Encrypt16(byte[] Input, int InOffset, byte[] Output, int OutOffset)
        {
            int LRD    = _expKey.Length - 5;
            int keyCtr = -1;

            // input round
            uint R0 = IntUtils.BytesToBe32(Input, InOffset + 12);
            uint R1 = IntUtils.BytesToBe32(Input, InOffset + 8);
            uint R2 = IntUtils.BytesToBe32(Input, InOffset + 4);
            uint R3 = IntUtils.BytesToBe32(Input, InOffset);

            // process 8 round blocks
            do
            {
                R0 ^= _expKey[++keyCtr];
                R1 ^= _expKey[++keyCtr];
                R2 ^= _expKey[++keyCtr];
                R3 ^= _expKey[++keyCtr];
                Sb0(ref R0, ref R1, ref R2, ref R3);
                LinearTransform(ref R0, ref R1, ref R2, ref R3);

                R0 ^= _expKey[++keyCtr];
                R1 ^= _expKey[++keyCtr];
                R2 ^= _expKey[++keyCtr];
                R3 ^= _expKey[++keyCtr];
                Sb1(ref R0, ref R1, ref R2, ref R3);
                LinearTransform(ref R0, ref R1, ref R2, ref R3);

                R0 ^= _expKey[++keyCtr];
                R1 ^= _expKey[++keyCtr];
                R2 ^= _expKey[++keyCtr];
                R3 ^= _expKey[++keyCtr];
                Sb2(ref R0, ref R1, ref R2, ref R3);
                LinearTransform(ref R0, ref R1, ref R2, ref R3);;

                R0 ^= _expKey[++keyCtr];
                R1 ^= _expKey[++keyCtr];
                R2 ^= _expKey[++keyCtr];
                R3 ^= _expKey[++keyCtr];
                Sb3(ref R0, ref R1, ref R2, ref R3);
                LinearTransform(ref R0, ref R1, ref R2, ref R3);

                R0 ^= _expKey[++keyCtr];
                R1 ^= _expKey[++keyCtr];
                R2 ^= _expKey[++keyCtr];
                R3 ^= _expKey[++keyCtr];
                Sb4(ref R0, ref R1, ref R2, ref R3);
                LinearTransform(ref R0, ref R1, ref R2, ref R3);

                R0 ^= _expKey[++keyCtr];
                R1 ^= _expKey[++keyCtr];
                R2 ^= _expKey[++keyCtr];
                R3 ^= _expKey[++keyCtr];
                Sb5(ref R0, ref R1, ref R2, ref R3);
                LinearTransform(ref R0, ref R1, ref R2, ref R3);

                R0 ^= _expKey[++keyCtr];
                R1 ^= _expKey[++keyCtr];
                R2 ^= _expKey[++keyCtr];
                R3 ^= _expKey[++keyCtr];
                Sb6(ref R0, ref R1, ref R2, ref R3);
                LinearTransform(ref R0, ref R1, ref R2, ref R3);

                R0 ^= _expKey[++keyCtr];
                R1 ^= _expKey[++keyCtr];
                R2 ^= _expKey[++keyCtr];
                R3 ^= _expKey[++keyCtr];
                Sb7(ref R0, ref R1, ref R2, ref R3);

                // skip on last block
                if (keyCtr != LRD)
                {
                    LinearTransform(ref R0, ref R1, ref R2, ref R3);
                }
            }while (keyCtr != LRD);

            // last round
            IntUtils.Be32ToBytes(_expKey[++keyCtr] ^ R0, Output, OutOffset + 12);
            IntUtils.Be32ToBytes(_expKey[++keyCtr] ^ R1, Output, OutOffset + 8);
            IntUtils.Be32ToBytes(_expKey[++keyCtr] ^ R2, Output, OutOffset + 4);
            IntUtils.Be32ToBytes(_expKey[++keyCtr] ^ R3, Output, OutOffset);
        }
Exemple #6
0
        private void Decrypt16(byte[] Input, int InOffset, byte[] Output, int OutOffset)
        {
            int LRD    = 4;
            int keyCtr = _expKey.Length;

            // input round
            uint R3 = _expKey[--keyCtr] ^ IntUtils.BytesToBe32(Input, InOffset);
            uint R2 = _expKey[--keyCtr] ^ IntUtils.BytesToBe32(Input, InOffset + 4);
            uint R1 = _expKey[--keyCtr] ^ IntUtils.BytesToBe32(Input, InOffset + 8);
            uint R0 = _expKey[--keyCtr] ^ IntUtils.BytesToBe32(Input, InOffset + 12);

            // process 8 round blocks
            do
            {
                Ib7(ref R0, ref R1, ref R2, ref R3);
                R3 ^= _expKey[--keyCtr];
                R2 ^= _expKey[--keyCtr];
                R1 ^= _expKey[--keyCtr];
                R0 ^= _expKey[--keyCtr];
                InverseTransform(ref R0, ref R1, ref R2, ref R3);

                Ib6(ref R0, ref R1, ref R2, ref R3);
                R3 ^= _expKey[--keyCtr];
                R2 ^= _expKey[--keyCtr];
                R1 ^= _expKey[--keyCtr];
                R0 ^= _expKey[--keyCtr];
                InverseTransform(ref R0, ref R1, ref R2, ref R3);

                Ib5(ref R0, ref R1, ref R2, ref R3);
                R3 ^= _expKey[--keyCtr];
                R2 ^= _expKey[--keyCtr];
                R1 ^= _expKey[--keyCtr];
                R0 ^= _expKey[--keyCtr];
                InverseTransform(ref R0, ref R1, ref R2, ref R3);

                Ib4(ref R0, ref R1, ref R2, ref R3);
                R3 ^= _expKey[--keyCtr];
                R2 ^= _expKey[--keyCtr];
                R1 ^= _expKey[--keyCtr];
                R0 ^= _expKey[--keyCtr];
                InverseTransform(ref R0, ref R1, ref R2, ref R3);

                Ib3(ref R0, ref R1, ref R2, ref R3);
                R3 ^= _expKey[--keyCtr];
                R2 ^= _expKey[--keyCtr];
                R1 ^= _expKey[--keyCtr];
                R0 ^= _expKey[--keyCtr];
                InverseTransform(ref R0, ref R1, ref R2, ref R3);

                Ib2(ref R0, ref R1, ref R2, ref R3);
                R3 ^= _expKey[--keyCtr];
                R2 ^= _expKey[--keyCtr];
                R1 ^= _expKey[--keyCtr];
                R0 ^= _expKey[--keyCtr];
                InverseTransform(ref R0, ref R1, ref R2, ref R3);

                Ib1(ref R0, ref R1, ref R2, ref R3);
                R3 ^= _expKey[--keyCtr];
                R2 ^= _expKey[--keyCtr];
                R1 ^= _expKey[--keyCtr];
                R0 ^= _expKey[--keyCtr];
                InverseTransform(ref R0, ref R1, ref R2, ref R3);

                Ib0(ref R0, ref R1, ref R2, ref R3);

                // skip on last block
                if (keyCtr != LRD)
                {
                    R3 ^= _expKey[--keyCtr];
                    R2 ^= _expKey[--keyCtr];
                    R1 ^= _expKey[--keyCtr];
                    R0 ^= _expKey[--keyCtr];
                    InverseTransform(ref R0, ref R1, ref R2, ref R3);
                }
            }while (keyCtr != LRD);

            // last round
            IntUtils.Be32ToBytes(R3 ^ _expKey[--keyCtr], Output, OutOffset);
            IntUtils.Be32ToBytes(R2 ^ _expKey[--keyCtr], Output, OutOffset + 4);
            IntUtils.Be32ToBytes(R1 ^ _expKey[--keyCtr], Output, OutOffset + 8);
            IntUtils.Be32ToBytes(R0 ^ _expKey[--keyCtr], Output, OutOffset + 12);
        }
Exemple #7
0
        private UInt32[] ExpandKey(byte[] Key)
        {
            int cnt     = 0;
            int index   = 0;
            int padSize = Key.Length < 32 ? 16 : Key.Length / 2;

            UInt32[] Wp     = new UInt32[padSize];
            int      offset = 0;

            // less than 512 is default rounds
            if (Key.Length < 64)
            {
                _dfnRounds = ROUNDS32;
            }

            int keySize = 4 * (_dfnRounds + 1);

            // step 1: reverse copy key to temp array
            for (offset = Key.Length; offset > 0; offset -= 4)
            {
                Wp[index++] = IntUtils.BytesToBe32(Key, offset - 4);
            }

            // pad small key
            if (index < 8)
            {
                Wp[index] = 1;
            }

            // initialize the key
            UInt32[] Wk = new UInt32[keySize];

            if (padSize == 16)
            {
                // 32 byte key
                // step 2: rotate k into w(k) ints
                for (int i = 8; i < 16; i++)
                {
                    Wp[i] = IntUtils.RotateLeft((UInt32)(Wp[i - 8] ^ Wp[i - 5] ^ Wp[i - 3] ^ Wp[i - 1] ^ PHI ^ (i - 8)), 11);
                }

                // copy to expanded key
                Array.Copy(Wp, 8, Wk, 0, 8);

                // step 3: calculate remainder of rounds with rotating primitive
                for (int i = 8; i < keySize; i++)
                {
                    Wk[i] = IntUtils.RotateLeft((UInt32)(Wk[i - 8] ^ Wk[i - 5] ^ Wk[i - 3] ^ Wk[i - 1] ^ PHI ^ i), 11);
                }
            }
            else
            {
                // *extended*: 64 byte key
                // step 3: rotate k into w(k) ints, with extended polynominal
                // Wp := (Wp-16 ^ Wp-13 ^ Wp-11 ^ Wp-10 ^ Wp-8 ^ Wp-5 ^ Wp-3 ^ Wp-1 ^ PHI ^ i) <<< 11
                for (int i = 16; i < 32; i++)
                {
                    Wp[i] = IntUtils.RotateLeft((UInt32)(Wp[i - 16] ^ Wp[i - 13] ^ Wp[i - 11] ^ Wp[i - 10] ^ Wp[i - 8] ^ Wp[i - 5] ^ Wp[i - 3] ^ Wp[i - 1] ^ PHI ^ (i - 16)), 11);
                }

                // copy to expanded key
                Array.Copy(Wp, 16, Wk, 0, 16);

                // step 3: calculate remainder of rounds with rotating primitive
                for (int i = 16; i < keySize; i++)
                {
                    Wk[i] = IntUtils.RotateLeft((UInt32)(Wk[i - 16] ^ Wk[i - 13] ^ Wk[i - 11] ^ Wk[i - 10] ^ Wk[i - 8] ^ Wk[i - 5] ^ Wk[i - 3] ^ Wk[i - 1] ^ PHI ^ i), 11);
                }
            }

            // step 4: create the working keys by processing with the Sbox and IP
            while (cnt < keySize - 4)
            {
                Sb3(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4;
                Sb2(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4;
                Sb1(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4;
                Sb0(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4;
                Sb7(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4;
                Sb6(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4;
                Sb5(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4;
                Sb4(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4;
            }

            // last round
            Sb3(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]);

            return(Wk);
        }