Beispiel #1
0
        private static int do_cast_setkey(ref CAST5_context c, byte[] key)
        {
            int i;

            uint[] x = new uint[4];
            uint[] z = new uint[4];
            uint[] k = new uint[16];

            x[0] = (uint)(key[0] << 24) | (uint)(key[1] << 16) | (uint)(key[2] << 8) | key[3];
            x[1] = (uint)(key[4] << 24) | (uint)(key[5] << 16) | (uint)(key[6] << 8) | key[7];
            x[2] = (uint)(key[8] << 24) | (uint)(key[9] << 16) | (uint)(key[10] << 8) | key[11];
            x[3] = (uint)(key[12] << 24) | (uint)(key[13] << 16) | (uint)(key[14] << 8) | key[15];

            key_schedule(x, z, k);
            for (i = 0; i < 16; i++)
            {
                c.Km[i] = k[i];
            }
            key_schedule(x, z, k);
            for (i = 0; i < 16; i++)
            {
                c.Kr[i] = (byte)(k[i] & 0x1f);
            }

            x.Initialize();
            z.Initialize();
            k.Initialize();

            return(0);
        }
Beispiel #2
0
        private static byte[] decrypt_block(ref CAST5_context c, byte[] inbuf)
        {
            byte[] outbuf = do_decrypt_block(ref c, inbuf);
            burn_stack(20 + 4 * outbuf.Length);

            return(outbuf);
        }
Beispiel #3
0
        private static CAST5_context cast_setkey(byte[] key)
        {
            CAST5_context c = new CAST5_context();

            c.Km = new uint[16];
            c.Kr = new byte[16];
            do_cast_setkey(ref c, key);
            burn_stack(96 + 7 * key.Length);
            return(c);
        }
Beispiel #4
0
        private static byte[] do_encrypt_block(ref CAST5_context c, byte[] inbuf)
        {
            byte[] outbuf = new byte[8];
            uint   l, r, t;

            uint[] Km;
            byte[] Kr;

            Km = c.Km;
            Kr = c.Kr;

            /* (L0,R0) <-- (m1...m64).	(Split the plaintext into left and
             * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
             */
            l = (uint)(inbuf[0] << 24) | (uint)(inbuf[1] << 16) | (uint)(inbuf[2] << 8) | (uint)inbuf[3];
            r = (uint)inbuf[4] << 24 | (uint)(inbuf[5] << 16) | (uint)(inbuf[6] << 8) | (uint)inbuf[7];

            /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
             *	Li = Ri-1;
             *	Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2
             * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
             * Rounds 2, 5, 8, 11, and 14 use f function Type 2.
             * Rounds 3, 6, 9, 12, and 15 use f function Type 3.
             */

            t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
            t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
            t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
            t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
            t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
            t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
            t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
            t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
            t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
            t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
            t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
            t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
            t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
            t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
            t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
            t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);

            /* c1...c64 <-- (R16,L16).	(Exchange final blocks L16, R16 and
             *	concatenate to form the ciphertext.) */
            outbuf[0] = (byte)((r >> 24) & 0xff);
            outbuf[1] = (byte)((r >> 16) & 0xff);
            outbuf[2] = (byte)((r >> 8) & 0xff);
            outbuf[3] = (byte)(r & 0xff);
            outbuf[4] = (byte)((l >> 24) & 0xff);
            outbuf[5] = (byte)((l >> 16) & 0xff);
            outbuf[6] = (byte)((l >> 8) & 0xff);
            outbuf[7] = (byte)(l & 0xff);

            return(outbuf);
        }
Beispiel #5
0
        private static byte[] do_decrypt_block(ref CAST5_context c, byte[] inbuf)
        {
            byte[] outbuf = new byte[8];
            uint   l, r, t;

            uint[] Km;
            byte[] Kr;

            Km = c.Km;
            Kr = c.Kr;

            l = (uint)(inbuf[0] << 24) | (uint)(inbuf[1] << 16) | (uint)(inbuf[2] << 8) | (uint)inbuf[3];
            r = (uint)(inbuf[4] << 24) | (uint)(inbuf[5] << 16) | (uint)(inbuf[6] << 8) | (uint)inbuf[7];

            t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
            t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
            t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
            t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
            t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
            t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
            t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
            t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
            t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
            t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
            t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
            t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
            t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
            t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
            t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
            t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);

            outbuf[0] = (byte)((r >> 24) & 0xff);
            outbuf[1] = (byte)((r >> 16) & 0xff);
            outbuf[2] = (byte)((r >> 8) & 0xff);
            outbuf[3] = (byte)(r & 0xff);
            outbuf[4] = (byte)((l >> 24) & 0xff);
            outbuf[5] = (byte)((l >> 16) & 0xff);
            outbuf[6] = (byte)((l >> 8) & 0xff);
            outbuf[7] = (byte)(l & 0xff);

            return(outbuf);
        }
        private static byte[] encrypt_block(ref CAST5_context c, byte[] inbuf)
        {
            byte[] outbuf = do_encrypt_block(ref c, inbuf);
            burn_stack(20+4*outbuf.Length);

            return outbuf;
        }
        private static byte[] do_encrypt_block(ref CAST5_context c, byte[] inbuf)
        {
            byte[] outbuf = new byte[8];
            uint l, r, t;
            uint[] Km;
            byte[] Kr;

            Km = c.Km;
            Kr = c.Kr;

            /* (L0,R0) <-- (m1...m64).	(Split the plaintext into left and
             * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
             */
            l = (uint)(inbuf[0] << 24) | (uint)(inbuf[1] << 16) | (uint)(inbuf[2] << 8) | (uint)inbuf[3];
            r = (uint)inbuf[4] << 24 | (uint)(inbuf[5] << 16) | (uint)(inbuf[6] << 8) | (uint)inbuf[7];

            /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
             *	Li = Ri-1;
             *	Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2
             * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
             * Rounds 2, 5, 8, 11, and 14 use f function Type 2.
             * Rounds 3, 6, 9, 12, and 15 use f function Type 3.
             */

            t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
            t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
            t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
            t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
            t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
            t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
            t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
            t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
            t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
            t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
            t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
            t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
            t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
            t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
            t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
            t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);

            /* c1...c64 <-- (R16,L16).	(Exchange final blocks L16, R16 and
             *	concatenate to form the ciphertext.) */
            outbuf[0] = (byte)((r >> 24) & 0xff);
            outbuf[1] = (byte)((r >> 16) & 0xff);
            outbuf[2] = (byte)((r >>  8) & 0xff);
            outbuf[3] = (byte)( r        & 0xff);
            outbuf[4] = (byte)((l >> 24) & 0xff);
            outbuf[5] = (byte)((l >> 16) & 0xff);
            outbuf[6] = (byte)((l >>  8) & 0xff);
            outbuf[7] = (byte)( l	     & 0xff);

            return outbuf;
        }
        private static byte[] do_decrypt_block(ref CAST5_context c, byte[] inbuf)
        {
            byte[] outbuf = new byte[8];
            uint l, r, t;
            uint[] Km;
            byte[] Kr;

            Km = c.Km;
            Kr = c.Kr;

            l = (uint)(inbuf[0] << 24) | (uint)(inbuf[1] << 16) | (uint)(inbuf[2] << 8) | (uint)inbuf[3];
            r = (uint)(inbuf[4] << 24) | (uint)(inbuf[5] << 16) | (uint)(inbuf[6] << 8) | (uint)inbuf[7];

            t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
            t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
            t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
            t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
            t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
            t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
            t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
            t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
            t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
            t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
            t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
            t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
            t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
            t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
            t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
            t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);

            outbuf[0] = (byte)((r >> 24) & 0xff);
            outbuf[1] = (byte)((r >> 16) & 0xff);
            outbuf[2] = (byte)((r >>  8) & 0xff);
            outbuf[3] = (byte)( r	     & 0xff);
            outbuf[4] = (byte)((l >> 24) & 0xff);
            outbuf[5] = (byte)((l >> 16) & 0xff);
            outbuf[6] = (byte)((l >>  8) & 0xff);
            outbuf[7] = (byte)( l	     & 0xff);

            return outbuf;
        }
        private static int do_cast_setkey(ref CAST5_context c, byte[] key)
        {
            int i;
            uint[] x = new uint[4];
            uint[] z = new uint[4];
            uint[] k = new uint[16];

            x[0] = (uint)(key[0]  << 24) | (uint)(key[1]  << 16) | (uint)(key[2]  << 8) | key[3];
            x[1] = (uint)(key[4]  << 24) | (uint)(key[5]  << 16) | (uint)(key[6]  << 8) | key[7];
            x[2] = (uint)(key[8]  << 24) | (uint)(key[9]  << 16) | (uint)(key[10] << 8) | key[11];
            x[3] = (uint)(key[12] << 24) | (uint)(key[13] << 16) | (uint)(key[14] << 8) | key[15];

            key_schedule(x, z, k);
            for(i=0; i < 16; i++)
                c.Km[i] = k[i];
            key_schedule(x, z, k);
            for(i=0; i < 16; i++)
                c.Kr[i] = (byte)(k[i] & 0x1f);

            x.Initialize();
            z.Initialize();
            k.Initialize();

            return 0;
        }
 private static CAST5_context cast_setkey(byte[] key)
 {
     CAST5_context c = new CAST5_context();
     c.Km = new uint[16];
     c.Kr = new byte[16];
     do_cast_setkey(ref c, key);
     burn_stack(96+7*key.Length);
     return c;
 }
        public static bool selftest()
        {
            CAST5_context c = new CAST5_context();
            //int i;

            // simple selftest
            byte[] key = {0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
                    0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};

            byte[] simple_plaintext = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
            byte[] simple_ciphertext = {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2};

            c = cast_setkey(key);
            byte[] encrypted = encrypt_block(ref c, simple_plaintext);

            for (int i=0; i<encrypted.Length; i++)
                if (simple_ciphertext[i] != encrypted[i])
                    return false;

            // strong selftest as in RFC 2144
            byte[] a = new byte[16];
            byte[] b = new byte[16];
            byte[] aL = {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78};
            byte[] aR = {0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A};
            byte[] bL = {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78};
            byte[] bR = {0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A};

            byte[] verify_a = {0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92};
            byte[] verify_b = {0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E};

            for (int i=0; i < 1000000; i++) {
                Array.Copy(bL, b, 8);
                Array.Copy(bR, 0, b, 8, 8);
                c = cast_setkey(b);
                aL = encrypt_block(ref c, aL);
                aR = encrypt_block(ref c, aR);
                Array.Copy(aL, a, 8);
                Array.Copy(aR, 0, a, 8, 8);

                c = cast_setkey(a);
                bL = encrypt_block(ref c, bL);
                bR = encrypt_block(ref c, bR);
            }

            Array.Copy(bL, b, 8);
            Array.Copy(bR, 0, b, 8, 8);
            Array.Copy(aL, a, 8);
            Array.Copy(aR, 0, a, 8, 8);

            for (int i=0; i<a.Length; i++)
                if (a[i] != verify_a[i])
                    return false;

            for (int i=0; i<b.Length; i++)
                if (b[i] != verify_b[i])
                    return false;

            return true;
        }
 /// <summary>
 /// Default constructor - initializes all fields to default values
 /// </summary>
 public CAST5Transform(CAST5 baseClass, bool isEncryption)
     : base(baseClass, isEncryption, baseClass.IV)
 {
     this.baseClass = baseClass;
     this.encrypt = isEncryption;
     c = cast_setkey(baseClass.Key);
 }
Beispiel #13
0
        public static bool selftest()
        {
            CAST5_context c = new CAST5_context();

            //int i;

            // simple selftest
            byte[] key = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
                           0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A };

            byte[] simple_plaintext  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
            byte[] simple_ciphertext = { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };

            c = cast_setkey(key);
            byte[] encrypted = encrypt_block(ref c, simple_plaintext);

            for (int i = 0; i < encrypted.Length; i++)
            {
                if (simple_ciphertext[i] != encrypted[i])
                {
                    return(false);
                }
            }

            // strong selftest as in RFC 2144
            byte[] a  = new byte[16];
            byte[] b  = new byte[16];
            byte[] aL = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78 };
            byte[] aR = { 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A };
            byte[] bL = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78 };
            byte[] bR = { 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A };

            byte[] verify_a = { 0xEE, 0xA9, 0xD0, 0xA2, 0x49, 0xFD, 0x3B, 0xA6, 0xB3, 0x43, 0x6F, 0xB8, 0x9D, 0x6D, 0xCA, 0x92 };
            byte[] verify_b = { 0xB2, 0xC9, 0x5E, 0xB0, 0x0C, 0x31, 0xAD, 0x71, 0x80, 0xAC, 0x05, 0xB8, 0xE8, 0x3D, 0x69, 0x6E };


            for (int i = 0; i < 1000000; i++)
            {
                Array.Copy(bL, b, 8);
                Array.Copy(bR, 0, b, 8, 8);
                c  = cast_setkey(b);
                aL = encrypt_block(ref c, aL);
                aR = encrypt_block(ref c, aR);
                Array.Copy(aL, a, 8);
                Array.Copy(aR, 0, a, 8, 8);

                c  = cast_setkey(a);
                bL = encrypt_block(ref c, bL);
                bR = encrypt_block(ref c, bR);
            }

            Array.Copy(bL, b, 8);
            Array.Copy(bR, 0, b, 8, 8);
            Array.Copy(aL, a, 8);
            Array.Copy(aR, 0, a, 8, 8);

            for (int i = 0; i < a.Length; i++)
            {
                if (a[i] != verify_a[i])
                {
                    return(false);
                }
            }

            for (int i = 0; i < b.Length; i++)
            {
                if (b[i] != verify_b[i])
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #14
0
 /// <summary>
 /// Default constructor - initializes all fields to default values
 /// </summary>
 public CAST5Transform(CAST5 baseClass, bool isEncryption) : base(baseClass, isEncryption, baseClass.IV)
 {
     this.baseClass = baseClass;
     this.encrypt   = isEncryption;
     c = cast_setkey(baseClass.Key);
 }