Esempio n. 1
0
        private static int F32(int k64Cnt, int x, int[] k32)
        {
            int b0 = Twofish_Algorithm.b0(x);
            int b1 = Twofish_Algorithm.b1(x);
            int b2 = Twofish_Algorithm.b2(x);
            int b3 = Twofish_Algorithm.b3(x);
            int k0 = k32[0];
            int k1 = k32[1];
            int k2 = k32[2];
            int k3 = k32[3];

            int result = 0;

            switch (k64Cnt & 3)
            {
            case 1:
                result = MDS[0][(P[P_01][b0] & 0xFF) ^ Twofish_Algorithm.b0(k0)] ^ MDS[1][(P[P_11][b1] & 0xFF) ^ Twofish_Algorithm.b1(k0)] ^ MDS[2][(P[P_21][b2] & 0xFF) ^ Twofish_Algorithm.b2(k0)] ^ MDS[3][(P[P_31][b3] & 0xFF) ^ Twofish_Algorithm.b3(k0)];
                break;

            case 0:
                // same as 4
                b0 = (P[P_04][b0] & 0xFF) ^ Twofish_Algorithm.b0(k3);
                b1 = (P[P_14][b1] & 0xFF) ^ Twofish_Algorithm.b1(k3);
                b2 = (P[P_24][b2] & 0xFF) ^ Twofish_Algorithm.b2(k3);
                b3 = (P[P_34][b3] & 0xFF) ^ Twofish_Algorithm.b3(k3);
                goto case 3;

            case 3:
                b0 = (P[P_03][b0] & 0xFF) ^ Twofish_Algorithm.b0(k2);
                b1 = (P[P_13][b1] & 0xFF) ^ Twofish_Algorithm.b1(k2);
                b2 = (P[P_23][b2] & 0xFF) ^ Twofish_Algorithm.b2(k2);
                b3 = (P[P_33][b3] & 0xFF) ^ Twofish_Algorithm.b3(k2);
                goto case 2;

            case 2:
                // 128-bit keys (optimize for this case)
                result = MDS[0][(P[P_01][(P[P_02][b0] & 0xFF) ^ Twofish_Algorithm.b0(k1)] & 0xFF) ^ Twofish_Algorithm.b0(k0)] ^ MDS[1][(P[P_11][(P[P_12][b1] & 0xFF) ^ Twofish_Algorithm.b1(k1)] & 0xFF) ^ Twofish_Algorithm.b1(k0)] ^ MDS[2][(P[P_21][(P[P_22][b2] & 0xFF) ^ Twofish_Algorithm.b2(k1)] & 0xFF) ^ Twofish_Algorithm.b2(k0)] ^ MDS[3][(P[P_31][(P[P_32][b3] & 0xFF) ^ Twofish_Algorithm.b3(k1)] & 0xFF) ^ Twofish_Algorithm.b3(k0)];
                break;
            }
            return(result);
        }
Esempio n. 2
0
        // EF


        // Basic API methods
        //...........................................................................

        /// <summary> Expand a user-supplied key material into a session key.
        /// *
        /// </summary>
        /// <param name="key"> The 64/128/192/256-bit user-key to use.
        /// </param>
        /// <returns> This cipher's round keys.
        /// </returns>
        /// <exception cref=""> ApplicationException  If the key is invalid.
        ///
        /// </exception>
        public static System.Object makeKey(byte[] k)
        {
            lock (typeof(Twofish.Twofish_Algorithm))
            {
                if (DEBUG)
                {
                    trace(IN, "makeKey(" + k + ")");
                }
                if (k == null)
                {
                    //UPGRADE_TODO: Constructor java.security.ApplicationException.ApplicationException was not converted. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1095"'
                    throw new ApplicationException("Empty key");
                }
                int length = k.Length;
                if (!(length == 8 || length == 16 || length == 24 || length == 32))
                {
                    //UPGRADE_TODO: Constructor java.security.ApplicationException.ApplicationException was not converted. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1095"'
                    throw new ApplicationException("Incorrect key length");
                }

                if (DEBUG && debuglevel > 7)
                {
                    System.Console.Out.WriteLine("Intermediate Session Key Values");
                    System.Console.Out.WriteLine();
                    System.Console.Out.WriteLine("Raw=" + toString(k));
                    System.Console.Out.WriteLine();
                }
                int   k64Cnt    = length / 8;
                int   subkeyCnt = ROUND_SUBKEYS + 2 * ROUNDS;
                int[] k32e      = new int[4];            // even 32-bit entities
                int[] k32o      = new int[4];            // odd 32-bit entities
                int[] sBoxKey   = new int[4];
                //
                // split user key material into even and odd 32-bit entities and
                // compute S-box keys using (12, 8) Reed-Solomon code over GF(256)
                //
                int i, j, offset = 0;
                for (i = 0, j = k64Cnt - 1; i < 4 && offset < length; i++, j--)
                {
                    k32e[i]    = (k[offset++] & 0xFF) | (k[offset++] & 0xFF) << 8 | (k[offset++] & 0xFF) << 16 | (k[offset++] & 0xFF) << 24;
                    k32o[i]    = (k[offset++] & 0xFF) | (k[offset++] & 0xFF) << 8 | (k[offset++] & 0xFF) << 16 | (k[offset++] & 0xFF) << 24;
                    sBoxKey[j] = RS_MDS_Encode(k32e[i], k32o[i]);                     // reverse order
                }
                // compute the round decryption subkeys for PHT. these same subkeys
                // will be used in encryption but will be applied in reverse order.
                int   q, A, B;
                int[] subKeys = new int[subkeyCnt];
                for (i = q = 0; i < subkeyCnt / 2; i++, q += SK_STEP)
                {
                    A  = F32(k64Cnt, q, k32e);                    // A uses even key entities
                    B  = F32(k64Cnt, q + SK_BUMP, k32o);          // B uses odd  key entities
                    B  = B << 8 | URShift(B, 24);
                    A += B;
                    subKeys[2 * i] = A;                     // combine with a PHT
                    A += B;
                    subKeys[2 * i + 1] = A << SK_ROTL | URShift(A, (32 - SK_ROTL));
                }
                //
                // fully expand the table for speed
                //
                int   k0 = sBoxKey[0];
                int   k1 = sBoxKey[1];
                int   k2 = sBoxKey[2];
                int   k3 = sBoxKey[3];
                int   b0, b1, b2, b3;
                int[] sBox = new int[4 * 256];
                for (i = 0; i < 256; i++)
                {
                    b0 = b1 = b2 = b3 = i;
                    switch (k64Cnt & 3)
                    {
                    case 1:
                        sBox[2 * i]             = MDS[0][(P[P_01][b0] & 0xFF) ^ Twofish_Algorithm.b0(k0)];
                        sBox[2 * i + 1]         = MDS[1][(P[P_11][b1] & 0xFF) ^ Twofish_Algorithm.b1(k0)];
                        sBox[0x200 + 2 * i]     = MDS[2][(P[P_21][b2] & 0xFF) ^ Twofish_Algorithm.b2(k0)];
                        sBox[0x200 + 2 * i + 1] = MDS[3][(P[P_31][b3] & 0xFF) ^ Twofish_Algorithm.b3(k0)];
                        break;

                    case 0:
                        // same as 4
                        b0 = (P[P_04][b0] & 0xFF) ^ Twofish_Algorithm.b0(k3);
                        b1 = (P[P_14][b1] & 0xFF) ^ Twofish_Algorithm.b1(k3);
                        b2 = (P[P_24][b2] & 0xFF) ^ Twofish_Algorithm.b2(k3);
                        b3 = (P[P_34][b3] & 0xFF) ^ Twofish_Algorithm.b3(k3);
                        goto case 3;

                    case 3:
                        b0 = (P[P_03][b0] & 0xFF) ^ Twofish_Algorithm.b0(k2);
                        b1 = (P[P_13][b1] & 0xFF) ^ Twofish_Algorithm.b1(k2);
                        b2 = (P[P_23][b2] & 0xFF) ^ Twofish_Algorithm.b2(k2);
                        b3 = (P[P_33][b3] & 0xFF) ^ Twofish_Algorithm.b3(k2);
                        goto case 2;

                    case 2:
                        // 128-bit keys
                        sBox[2 * i]             = MDS[0][(P[P_01][(P[P_02][b0] & 0xFF) ^ Twofish_Algorithm.b0(k1)] & 0xFF) ^ Twofish_Algorithm.b0(k0)];
                        sBox[2 * i + 1]         = MDS[1][(P[P_11][(P[P_12][b1] & 0xFF) ^ Twofish_Algorithm.b1(k1)] & 0xFF) ^ Twofish_Algorithm.b1(k0)];
                        sBox[0x200 + 2 * i]     = MDS[2][(P[P_21][(P[P_22][b2] & 0xFF) ^ Twofish_Algorithm.b2(k1)] & 0xFF) ^ Twofish_Algorithm.b2(k0)];
                        sBox[0x200 + 2 * i + 1] = MDS[3][(P[P_31][(P[P_32][b3] & 0xFF) ^ Twofish_Algorithm.b3(k1)] & 0xFF) ^ Twofish_Algorithm.b3(k0)];
                        break;
                    }
                }

                System.Object sessionKey = new System.Object[] { sBox, subKeys };

                if (DEBUG && debuglevel > 7)
                {
                    System.Console.Out.WriteLine("S-box[]:");
                    for (i = 0; i < 64; i++)
                    {
                        for (j = 0; j < 4; j++)
                        {
                            System.Console.Out.Write("0x" + intToString(sBox[i * 4 + j]) + ", ");
                        }
                        System.Console.Out.WriteLine();
                    }
                    System.Console.Out.WriteLine();
                    for (i = 0; i < 64; i++)
                    {
                        for (j = 0; j < 4; j++)
                        {
                            System.Console.Out.Write("0x" + intToString(sBox[256 + i * 4 + j]) + ", ");
                        }
                        System.Console.Out.WriteLine();
                    }
                    System.Console.Out.WriteLine();
                    for (i = 0; i < 64; i++)
                    {
                        for (j = 0; j < 4; j++)
                        {
                            System.Console.Out.Write("0x" + intToString(sBox[512 + i * 4 + j]) + ", ");
                        }
                        System.Console.Out.WriteLine();
                    }
                    System.Console.Out.WriteLine();
                    for (i = 0; i < 64; i++)
                    {
                        for (j = 0; j < 4; j++)
                        {
                            System.Console.Out.Write("0x" + intToString(sBox[768 + i * 4 + j]) + ", ");
                        }
                        System.Console.Out.WriteLine();
                    }
                    System.Console.Out.WriteLine();
                    System.Console.Out.WriteLine("User (odd, even) keys  --> S-Box keys:");
                    for (i = 0; i < k64Cnt; i++)
                    {
                        System.Console.Out.WriteLine("0x" + intToString(k32o[i]) + "  0x" + intToString(k32e[i]) + " --> 0x" + intToString(sBoxKey[k64Cnt - 1 - i]));
                    }
                    System.Console.Out.WriteLine();
                    System.Console.Out.WriteLine("Round keys:");
                    for (i = 0; i < ROUND_SUBKEYS + 2 * ROUNDS; i += 2)
                    {
                        System.Console.Out.WriteLine("0x" + intToString(subKeys[i]) + "  0x" + intToString(subKeys[i + 1]));
                    }
                    System.Console.Out.WriteLine();
                }
                if (DEBUG)
                {
                    trace(OUT, "makeKey()");
                }
                return(sessionKey);
            }
        }