Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/lib/crypto/twofishcipher.cc

Go to the documentation of this file.
00001 /*
00002  * lib/crypto/twofishcipher.cc 
00003  * 
00004  * Implementation of the twofish cipher. 
00005  * This is heavily adapted source from the international patch 
00006  * for the linux kernel. 
00007  * 
00008  * Adapted and maintained for HLIB by Wolfgang Wieser ] wwieser (a) gmx <*> de [. 
00009  *
00010  * NOTE: This implementation has been changed from the original
00011  * source. See ChangeLog for more information.
00012  * Maintained by Marc Mutz <Marc@Mutz.com>
00013  * 
00014  * Twofish for GPG
00015  * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
00016  * 256-bit key length added March 20, 1999
00017  * Some modifications to reduce the text size by Werner Koch, April, 1998
00018  * 
00019  * The original author has disclaimed all copyright interest in this
00020  * code and thus putting it in the public domain.
00021  * 
00022  * 
00023  * This file may be distributed and/or modified under the terms of the 
00024  * GNU General Public License version 2 as published by the Free Software 
00025  * Foundation. (See COPYING.GPL for details.)
00026  * 
00027  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00028  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00029  * 
00030  */
00031 
00032 #include "twofishcipher.h"
00033 
00034 
00035 /* The large precomputed tables for the Twofish cipher (twofish.c)
00036  * Taken from the same source as twofish.c
00037  * Marc Mutz <Marc@Mutz.com>
00038  */
00039 
00040 /* These two tables are the q0 and q1 permutations, exactly as described in
00041  * the Twofish paper. */
00042 
00043 static const uint8 q0[256] = {
00044    0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
00045    0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
00046    0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
00047    0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
00048    0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
00049    0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
00050    0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
00051    0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
00052    0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
00053    0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
00054    0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
00055    0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
00056    0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
00057    0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
00058    0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
00059    0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
00060    0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
00061    0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
00062    0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
00063    0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
00064    0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
00065    0x4A, 0x5E, 0xC1, 0xE0
00066 };
00067 
00068 static const uint8 q1[256] = {
00069    0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
00070    0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
00071    0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
00072    0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
00073    0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
00074    0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
00075    0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
00076    0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
00077    0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
00078    0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
00079    0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
00080    0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
00081    0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
00082    0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
00083    0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
00084    0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
00085    0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
00086    0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
00087    0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
00088    0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
00089    0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
00090    0x55, 0x09, 0xBE, 0x91
00091 };
00092 
00093 /* These MDS tables are actually tables of MDS composed with q0 and q1,
00094  * because it is only ever used that way and we can save some time by
00095  * precomputing.  Of course the main saving comes from precomputing the
00096  * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
00097  * things up in these tables we reduce the matrix multiply to four lookups
00098  * and three XORs.  Semi-formally, the definition of these tables is:
00099  * mds[0][i] = MDS (q1[i] 0 0 0)^T  mds[1][i] = MDS (0 q0[i] 0 0)^T
00100  * mds[2][i] = MDS (0 0 q1[i] 0)^T  mds[3][i] = MDS (0 0 0 q0[i])^T
00101  * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
00102  * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
00103  * by Schneier et al, and I'm casually glossing over the byte/word
00104  * conversion issues. */
00105 
00106 static const uint32 mds[4][256] = {
00107    {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
00108     0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
00109     0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
00110     0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
00111     0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
00112     0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
00113     0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
00114     0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
00115     0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
00116     0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
00117     0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
00118     0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
00119     0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
00120     0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
00121     0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
00122     0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
00123     0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
00124     0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
00125     0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
00126     0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
00127     0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
00128     0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
00129     0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
00130     0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
00131     0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
00132     0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
00133     0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
00134     0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
00135     0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
00136     0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
00137     0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
00138     0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
00139     0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
00140     0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
00141     0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
00142     0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
00143     0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
00144     0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
00145     0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
00146     0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
00147     0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
00148     0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
00149     0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
00150 
00151    {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
00152     0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
00153     0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
00154     0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
00155     0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
00156     0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
00157     0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
00158     0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
00159     0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
00160     0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
00161     0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
00162     0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
00163     0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
00164     0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
00165     0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
00166     0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
00167     0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
00168     0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
00169     0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
00170     0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
00171     0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
00172     0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
00173     0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
00174     0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
00175     0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
00176     0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
00177     0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
00178     0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
00179     0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
00180     0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
00181     0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
00182     0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
00183     0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
00184     0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
00185     0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
00186     0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
00187     0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
00188     0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
00189     0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
00190     0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
00191     0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
00192     0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
00193     0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
00194 
00195    {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
00196     0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
00197     0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
00198     0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
00199     0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
00200     0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
00201     0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
00202     0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
00203     0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
00204     0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
00205     0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
00206     0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
00207     0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
00208     0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
00209     0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
00210     0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
00211     0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
00212     0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
00213     0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
00214     0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
00215     0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
00216     0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
00217     0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
00218     0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
00219     0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
00220     0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
00221     0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
00222     0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
00223     0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
00224     0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
00225     0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
00226     0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
00227     0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
00228     0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
00229     0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
00230     0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
00231     0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
00232     0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
00233     0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
00234     0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
00235     0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
00236     0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
00237     0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
00238 
00239    {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
00240     0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
00241     0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
00242     0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
00243     0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
00244     0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
00245     0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
00246     0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
00247     0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
00248     0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
00249     0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
00250     0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
00251     0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
00252     0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
00253     0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
00254     0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
00255     0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
00256     0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
00257     0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
00258     0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
00259     0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
00260     0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
00261     0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
00262     0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
00263     0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
00264     0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
00265     0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
00266     0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
00267     0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
00268     0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
00269     0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
00270     0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
00271     0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
00272     0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
00273     0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
00274     0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
00275     0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
00276     0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
00277     0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
00278     0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
00279     0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
00280     0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
00281     0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
00282 };
00283 
00284 /* The exp_to_poly and poly_to_exp tables are used to perform efficient
00285  * operations in GF(2^8) represented as GF(2)[x]/w(x) where
00286  * w(x)=x^8+x^6+x^3+x^2+1.  We care about doing that because it's part of the
00287  * definition of the RS matrix in the key schedule.  Elements of that field
00288  * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
00289  * which can be represented naturally by bytes (just substitute x=2).  In that
00290  * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
00291  * multiplication is inefficient without hardware support.  To multiply
00292  * faster, I make use of the fact x is a generator for the nonzero elements,
00293  * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
00294  * some n in 0..254.  Note that that caret is exponentiation in GF(2^8),
00295  * *not* polynomial notation.  So if I want to compute pq where p and q are
00296  * in GF(2^8), I can just say:
00297  *    1. if p=0 or q=0 then pq=0
00298  *    2. otherwise, find m and n such that p=x^m and q=x^n
00299  *    3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
00300  * The translations in steps 2 and 3 are looked up in the tables
00301  * poly_to_exp (for step 2) and exp_to_poly (for step 3).  To see this
00302  * in action, look at the CALC_S macro.  As additional wrinkles, note that
00303  * one of my operands is always a constant, so the poly_to_exp lookup on it
00304  * is done in advance; I included the original values in the comments so
00305  * readers can have some chance of recognizing that this *is* the RS matrix
00306  * from the Twofish paper.  I've only included the table entries I actually
00307  * need; I never do a lookup on a variable input of zero and the biggest
00308  * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
00309  * never sum to more than 491.  I'm repeating part of the exp_to_poly table
00310  * so that I don't have to do mod-255 reduction in the exponent arithmetic.
00311  * Since I know my constant operands are never zero, I only have to worry
00312  * about zero values in the variable operand, and I do it with a simple
00313  * conditional branch.  I know conditionals are expensive, but I couldn't
00314  * see a non-horrible way of avoiding them, and I did manage to group the
00315  * statements so that each if covers four group multiplications. */
00316 
00317 static const uint8 poly_to_exp[255] = {
00318    0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
00319    0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
00320    0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
00321    0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
00322    0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
00323    0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
00324    0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
00325    0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
00326    0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
00327    0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
00328    0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
00329    0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
00330    0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
00331    0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
00332    0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
00333    0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
00334    0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
00335    0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
00336    0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
00337    0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
00338    0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
00339    0x85, 0xC8, 0xA1
00340 };
00341 
00342 static const uint8 exp_to_poly[492] = {
00343    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
00344    0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
00345    0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
00346    0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
00347    0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
00348    0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
00349    0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
00350    0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
00351    0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
00352    0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
00353    0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
00354    0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
00355    0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
00356    0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
00357    0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
00358    0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
00359    0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
00360    0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
00361    0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
00362    0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
00363    0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
00364    0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
00365    0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
00366    0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
00367    0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
00368    0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
00369    0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
00370    0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
00371    0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
00372    0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
00373    0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
00374    0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
00375    0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
00376    0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
00377    0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
00378    0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
00379    0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
00380    0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
00381    0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
00382    0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
00383    0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
00384 };
00385 
00386 
00387 /* The table constants are indices of
00388  * S-box entries, preprocessed through q0 and q1. */
00389 static const uint8 calc_sb_tbl[512] = {
00390     0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
00391     0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
00392     0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
00393     0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
00394     0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
00395     0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
00396     0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
00397     0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
00398     0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
00399     0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
00400     0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
00401     0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
00402     0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
00403     0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
00404     0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
00405     0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
00406     0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
00407     0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
00408     0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
00409     0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
00410     0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
00411     0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
00412     0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
00413     0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
00414     0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
00415     0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
00416     0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
00417     0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
00418     0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
00419     0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
00420     0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
00421     0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
00422     0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
00423     0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
00424     0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
00425     0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
00426     0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
00427     0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
00428     0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
00429     0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
00430     0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
00431     0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
00432     0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
00433     0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
00434     0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
00435     0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
00436     0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
00437     0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
00438     0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
00439     0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
00440     0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
00441     0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
00442     0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
00443     0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
00444     0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
00445     0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
00446     0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
00447     0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
00448     0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
00449     0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
00450     0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
00451     0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
00452     0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
00453     0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
00454 };
00455 
00456 
00457 /* NOTE: This implementation has been changed from the original
00458  * source. See ChangeLog for more information.
00459  * Maintained by Marc Mutz <Marc@Mutz.com>
00460  */
00461 
00462 /* Twofish for GPG
00463  * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
00464  * 256-bit key length added March 20, 1999
00465  * Some modifications to reduce the text size by Werner Koch, April, 1998
00466  *
00467  * The original author has disclaimed all copyright interest in this
00468  * code and thus putting it in the public domain.
00469  *
00470  * This code is a "clean room" implementation, written from the paper
00471  * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
00472  * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
00473  * through http://www.counterpane.com/twofish.html
00474  *
00475  * For background information on multiplication in finite fields, used for
00476  * the matrix operations in the key schedule, see the book _Contemporary
00477  * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
00478  * Third Edition.
00479  *
00480  * Only the 128- and 256-bit key sizes are supported.  This code is intended
00481  * for GNU C on a 32-bit system, but it should work almost anywhere.  Loops
00482  * are unrolled, precomputation tables are used, etc., for maximum speed at
00483  * some cost in memory consumption. */
00484  
00485 
00486 /* Macro to perform one column of the RS matrix multiplication.  The
00487  * parameters a, b, c, and d are the four bytes of output; i is the index
00488  * of the key bytes, and w, x, y, and z, are the column of constants from
00489  * the RS matrix, preprocessed through the poly_to_exp table. */
00490 
00491 #define CALC_Sx(sa,sb,sc,sd,ki,awxyzp) \
00492     if(*ik) \
00493     { \
00494         register const unsigned char *e2p=&exp_to_poly[poly_to_exp[(*ik)-1]];  \
00495         sa ^= e2p[*(awxyzp++)]; \
00496         sb ^= e2p[*(awxyzp++)]; \
00497         sc ^= e2p[*(awxyzp++)]; \
00498         sd ^= e2p[*(awxyzp++)]; \
00499     } \
00500     else \
00501     {  awxyzp+=4;  }
00502 
00503 #if 1
00504 static inline uint32 Xmds(unsigned char a,unsigned char b)
00505     {  return(mds[a][b]);  }
00506 static inline unsigned char Xq0(unsigned char a)
00507     {  return(q0[a]);  }
00508 static inline unsigned char Xq1(unsigned char a)
00509     {  return(q1[a]);  }
00510 #else
00511 #error DO NOT USE; WILL NOT WORK PROPERLY!!
00512 #define Xmds(a,b)  (mds[a][b])
00513 #define Xq0(a)     (q0[a])
00514 #define Xq1(a)     (q1[a])
00515 #endif
00516 
00517 
00518 /* Perform the key setup.  Note that this works only with 128- and 256-bit
00519  * keys, despite the API that looks like it might support other sizes. */
00520 int TwoFishCipher::SetKey(char *key,size_t keylen)
00521 {
00522     // Complete function: >8700 bytes on i386 
00523     
00524     if(keylen!=16 && keylen!=32)
00525     {  return(-2);  }
00526     
00527     uint32 x,y;   // temporaries 
00528     
00529     /* The S vector used to key the S-boxes, split up into individual bytes.
00530      * 128-bit keys use only sa through sh; 256-bit use all of them. */
00531     unsigned char sa=0,sb=0,sc=0,sd=0,se=0,sf=0,sg=0,sh=0;
00532     unsigned char si=0,sj=0,sk=0,sl=0,sm=0,sn=0,so=0,sp=0;
00533     
00534     static const unsigned char awxyz[32]=
00535         { 0x00, 0x2D, 0x01, 0x2D,
00536           0x2D, 0xA4, 0x44, 0x8A,
00537           0x8A, 0xD5, 0xBF, 0xD1,
00538           0xD1, 0x7F, 0x3D, 0x99,
00539           0x99, 0x46, 0x66, 0x96,
00540           0x96, 0x3C, 0x5B, 0xED,
00541           0xED, 0x37, 0x4F, 0xE0,
00542           0xE0, 0xD0, 0x8C, 0x17 };
00543     
00544     static const unsigned char aww[16]=
00545         { 0x9A,0x80,0xE4,0xD1,0x0D,0x35,0x18,0xEC,
00546           0x43,0x37,0xFA,0x94,0xF2,0x8B,0x84,0xDF };
00547     static const unsigned char axx[16]=
00548         { 0x4A,0xE6,0x45,0xE8,0xD6,0xD8,0x37,0xF1,
00549           0x30,0xF8,0x87,0x06,0x5E,0xAE,0x8A,0xBC };
00550     static const unsigned char ayy[16]=
00551         { 0x92,0x78,0xDD,0x38,0xC6,0x98,0xF7,0x6C,
00552           0x75,0x26,0x13,0x48,0xD0,0x30,0x54,0x23 };
00553     static const unsigned char azz[16]=
00554         { 0xD3,0x6B,0x7D,0x4B,0x32,0xFD,0x71,0xE1,
00555           0x0F,0x1B,0xFA,0x3F,0xBA,0x5B,0x00,0x9D };
00556     
00557     static const unsigned char bw[4]={ 0xA9,0xB3,0x04,0xA3 };
00558     static const unsigned char bx[4]={ 0x75,0xC6,0xDB,0xFB };
00559     static const unsigned char by[4]={ 0x67,0xE8,0xFD,0x76 };
00560     static const unsigned char bz[4]={ 0xF3,0xF4,0x7B,0xC8 };
00561     
00562     unsigned char *ik=(unsigned char*)key;
00563      
00564     /* Compute the first two words of the S vector.  The magic numbers are
00565      * the entries of the RS matrix, preprocessed through poly_to_exp. The
00566      * numbers in the comments are the original (polynomial form) matrix
00567      * entries. */
00568     // Both loops: <500 bytes on i386
00569     for(const unsigned char *awxyzp=awxyz,*awxyze=&awxyz[32]; 
00570         awxyzp<awxyze; ik++)
00571     {  CALC_Sx(sa,sb,sc,sd,ik,awxyzp);  }
00572     
00573     for(const unsigned char *awxyzp=awxyz,*awxyze=&awxyz[32]; 
00574         awxyzp<awxyze; ik++)
00575     {  CALC_Sx(se,sf,sg,sh,ik,awxyzp);  }
00576     
00577     if(keylen == 32)   // 256 bit key  
00578     {
00579         /* Calculate the remaining two words of the S vector */
00580         // Both loops: 350 bytes on i386
00581         for(const unsigned char *awxyzp=awxyz,*awxyze=&awxyz[32]; 
00582             awxyzp<awxyze; ik++)
00583         {  CALC_Sx(si,sj,sk,sl,ik,awxyzp);  }
00584         for(const unsigned char *awxyzp=awxyz,*awxyze=&awxyz[32]; 
00585             awxyzp<awxyze; ik++)
00586         {  CALC_Sx(sm,sn,so,sp,ik,awxyzp);  }
00587         
00588         /* Compute the S-boxes. */
00589         // <500 bytes on i386
00590         for(int i=0,j=0,k=1; i<256; i++,j+=2,k+=2)
00591         {
00592             this->c_s[0][i] = Xmds(0,Xq0(Xq0(Xq1(calc_sb_tbl[k] ^ sa) ^ se) ^ si) ^ sm);
00593             this->c_s[1][i] = Xmds(1,Xq0(Xq1(Xq1(calc_sb_tbl[j] ^ sb) ^ sf) ^ sj) ^ sn);
00594             this->c_s[2][i] = Xmds(2,Xq1(Xq0(Xq0(calc_sb_tbl[j] ^ sc) ^ sg) ^ sk) ^ so);
00595             this->c_s[3][i] = Xmds(3,Xq1(Xq1(Xq0(calc_sb_tbl[k] ^ sd) ^ sh) ^ sl) ^ sp);
00596         }
00597         
00598         // Calculate whitening and round subkeys.  The constants are
00599         // indices of subkeys, preprocessed through q0 and q1. 
00600         // about 800 bytes on i386
00601         {
00602             const unsigned char *bwp=bw,*bxp=bx,*byp=by,*bzp=bz;
00603             for(int _i=0; _i<4; _i++,bwp++,bxp++,byp++,bzp++)
00604             {
00605                 x = Xmds(0,Xq0(Xq0(Xq1((*bxp) ^ key[24]) ^ key[16]) ^ key[ 8]) ^ key[ 0]) ^ 
00606                     Xmds(1,Xq0(Xq1(Xq1((*bwp) ^ key[25]) ^ key[17]) ^ key[ 9]) ^ key[ 1]) ^ 
00607                     Xmds(2,Xq1(Xq0(Xq0((*bwp) ^ key[26]) ^ key[18]) ^ key[10]) ^ key[ 2]) ^ 
00608                     Xmds(3,Xq1(Xq1(Xq0((*bxp) ^ key[27]) ^ key[19]) ^ key[11]) ^ key[ 3]);
00609                 y = Xmds(0,Xq0(Xq0(Xq1((*bzp) ^ key[28]) ^ key[20]) ^ key[12]) ^ key[ 4]) ^ 
00610                     Xmds(1,Xq0(Xq1(Xq1((*byp) ^ key[29]) ^ key[21]) ^ key[13]) ^ key[ 5]) ^ 
00611                     Xmds(2,Xq1(Xq0(Xq0((*byp) ^ key[30]) ^ key[22]) ^ key[14]) ^ key[ 6]) ^ 
00612                     Xmds(3,Xq1(Xq1(Xq0((*bzp) ^ key[31]) ^ key[23]) ^ key[15]) ^ key[ 7]);
00613                 y = (y << 8) + (y >> 24);
00614                 x += y;
00615                 y += x;
00616                 this->c_w[ _i+_i   ] = x;
00617                 this->c_w[ _i+_i+1 ] = (y << 9) + (y >> 23) ;
00618             }
00619         }
00620     
00621         // about 800 bytes on i386
00622         {
00623             const unsigned char *awwp=aww,*axxp=axx,*ayyp=ayy,*azzp=azz;
00624             for(int _i=0; _i<16; _i++,awwp++,axxp++,ayyp++,azzp++)
00625             {
00626                 x = Xmds(0,Xq0(Xq0(Xq1((*axxp) ^ key[24]) ^ key[16]) ^ key[ 8]) ^ key[ 0]) ^ 
00627                     Xmds(1,Xq0(Xq1(Xq1((*awwp) ^ key[25]) ^ key[17]) ^ key[ 9]) ^ key[ 1]) ^ 
00628                     Xmds(2,Xq1(Xq0(Xq0((*awwp) ^ key[26]) ^ key[18]) ^ key[10]) ^ key[ 2]) ^ 
00629                     Xmds(3,Xq1(Xq1(Xq0((*axxp) ^ key[27]) ^ key[19]) ^ key[11]) ^ key[ 3]);
00630                 y = Xmds(0,Xq0(Xq0(Xq1((*azzp) ^ key[28]) ^ key[20]) ^ key[12]) ^ key[ 4]) ^ 
00631                     Xmds(1,Xq0(Xq1(Xq1((*ayyp) ^ key[29]) ^ key[21]) ^ key[13]) ^ key[ 5]) ^ 
00632                     Xmds(2,Xq1(Xq0(Xq0((*ayyp) ^ key[30]) ^ key[22]) ^ key[14]) ^ key[ 6]) ^ 
00633                     Xmds(3,Xq1(Xq1(Xq0((*azzp) ^ key[31]) ^ key[23]) ^ key[15]) ^ key[ 7]);
00634                 y = (y << 8) + (y >> 24);
00635                 x += y;
00636                 y += x;
00637                 this->c_k[ _i+_i   ] = x;
00638                 this->c_k[ _i+_i+1 ] = (y << 9) + (y >> 23) ;
00639             }
00640         }
00641     }
00642     else
00643     {
00644         /* Compute the S-boxes. */
00645         for(int i=0,j=0,k=1; i<256; i++,j+=2,k+=2)
00646         {
00647             this->c_s[0][i] = Xmds(0,Xq0(calc_sb_tbl[j] ^ sa) ^ se);
00648             this->c_s[1][i] = Xmds(1,Xq0(calc_sb_tbl[k] ^ sb) ^ sf);
00649             this->c_s[2][i] = Xmds(2,Xq1(calc_sb_tbl[j] ^ sc) ^ sg);
00650             this->c_s[3][i] = Xmds(3,Xq1(calc_sb_tbl[k] ^ sd) ^ sh);
00651         }
00652         
00653         // Calculate whitening and round subkeys.  The constants are
00654         // indices of subkeys, preprocessed through q0 and q1. 
00655         {
00656             const unsigned char *bwp=bw,*bxp=bx,*byp=by,*bzp=bz;
00657             for(int _i=0; _i<4; _i++,bwp++,bxp++,byp++,bzp++)
00658             {
00659                 x = Xmds(0,Xq0((*bwp) ^ key[ 8]) ^ key[ 0]) ^ 
00660                     Xmds(1,Xq0((*bxp) ^ key[ 9]) ^ key[ 1]) ^ 
00661                     Xmds(2,Xq1((*bwp) ^ key[10]) ^ key[ 2]) ^ 
00662                     Xmds(3,Xq1((*bxp) ^ key[11]) ^ key[ 3]);
00663                 y = Xmds(0,Xq0((*byp) ^ key[12]) ^ key[ 4]) ^ 
00664                     Xmds(1,Xq0((*bzp) ^ key[13]) ^ key[ 5]) ^ 
00665                     Xmds(2,Xq1((*byp) ^ key[14]) ^ key[ 6]) ^ 
00666                     Xmds(3,Xq1((*bzp) ^ key[15]) ^ key[ 7]);
00667                 y = (y << 8) + (y >> 24); 
00668                 x += y; y += x; 
00669                 this-> c_w [ _i+_i   ] = x; 
00670                 this-> c_w [ _i+_i+1 ] = (y << 9) + (y >> 23);
00671             }
00672         }
00673         
00674         {
00675             const unsigned char *awwp=aww,*axxp=axx,*ayyp=ayy,*azzp=azz;
00676             for(int _i=0; _i<16; _i++,awwp++,axxp++,ayyp++,azzp++)
00677             {
00678                 x = Xmds(0,Xq0((*awwp) ^ key[ 8]) ^ key[ 0]) ^ 
00679                     Xmds(1,Xq0((*axxp) ^ key[ 9]) ^ key[ 1]) ^ 
00680                     Xmds(2,Xq1((*awwp) ^ key[10]) ^ key[ 2]) ^ 
00681                     Xmds(3,Xq1((*axxp) ^ key[11]) ^ key[ 3]);
00682                 y = Xmds(0,Xq0((*ayyp) ^ key[12]) ^ key[ 4]) ^ 
00683                     Xmds(1,Xq0((*azzp) ^ key[13]) ^ key[ 5]) ^ 
00684                     Xmds(2,Xq1((*ayyp) ^ key[14]) ^ key[ 6]) ^ 
00685                     Xmds(3,Xq1((*azzp) ^ key[15]) ^ key[ 7]);
00686                 y = (y << 8) + (y >> 24);
00687                 x += y; y += x;
00688                 this-> c_k [ _i+_i   ] = x; 
00689                 this-> c_k [ _i+_i+1 ] = (y << 9) + (y >> 23);
00690             }
00691         }
00692     }
00693     
00694     return(0);
00695 }
00696 
00697 
00698 int TwoFishCipher::CheckWeakKey()
00699 {
00700     // Nothing known about weak keys. 
00701     return(0);
00702 }
00703 
00704 
00705 #define INPACK(a,in,idx) \
00706     a =uint32(*(in++))      ; \
00707     a|=uint32(*(in++)) <<  8; \
00708     a|=uint32(*(in++)) << 16; \
00709     a|=uint32(*(in++)) << 24; \
00710     a^=this->c_w[idx]; \
00711 
00712 #define OUTPACK(a,out,idx) \
00713     a ^= this->c_w[idx]; \
00714     *(out++) = a      ; \
00715     *(out++) = a >>  8; \
00716     *(out++) = a >> 16; \
00717     *(out++) = a >> 24; 
00718 
00719 
00720 /* Encrypt one block.  in and out may be the same. */
00721 void TwoFishCipher::EncryptBlock(char *ibuf,char *obuf)
00722 {
00723     // Complete function; <1000 bytes on i386. 
00724     
00725     unsigned char *in=(unsigned char*)ibuf;
00726     unsigned char *out=(unsigned char*)obuf;
00727 
00728     /* The four 32-bit chunks of the text. */
00729     uint32 a, b, c, d;
00730     
00731     /* Input whitening and packing. (200 bytes code on i386) */
00732     INPACK(a,in,0);
00733     INPACK(b,in,1);
00734     INPACK(c,in,2);
00735     INPACK(d,in,3);
00736     
00737     /* Encryption Feistel cycles. (<600 bytes on i386) */
00738     register uint32 y,x;
00739     for(int i=0; i<32; )
00740     {
00741         y=(this->c_s[1][ b        & 0xFF]) ^ 
00742           (this->c_s[2][(b >>  8) & 0xFF]) ^ 
00743           (this->c_s[3][(b >> 16) & 0xFF]) ^ 
00744           (this->c_s[0][ b >> 24        ]); 
00745         x=(this->c_s[0][ a        & 0xFF]) ^ 
00746           (this->c_s[1][(a >>  8) & 0xFF]) ^ 
00747           (this->c_s[2][(a >> 16) & 0xFF]) ^ 
00748           (this->c_s[3][ a >> 24        ]);
00749         x += y; 
00750         c ^= x + this->c_k[i++]; 
00751         y += x + this->c_k[i++]; 
00752         c  = (c >> 1) | (c << 31); 
00753         d  = ((d << 1) | (d >> 31)) ^ y;
00754         
00755         y=(this->c_s[1][ d        & 0xFF]) ^ 
00756           (this->c_s[2][(d >>  8) & 0xFF]) ^ 
00757           (this->c_s[3][(d >> 16) & 0xFF]) ^ 
00758           (this->c_s[0][ d >> 24        ]);
00759         x=(this->c_s[0][ c        & 0xFF]) ^ 
00760           (this->c_s[1][(c >>  8) & 0xFF]) ^ 
00761           (this->c_s[2][(c >> 16) & 0xFF]) ^ 
00762           (this->c_s[3][ c >> 24        ]);
00763         x += y; 
00764         a ^= x+this->c_k[i++]; 
00765         y += x+this->c_k[i++]; 
00766         a  = (a >> 1) | (a << 31); 
00767         b  = ((b << 1) | (b >> 31)) ^ y;  
00768     }
00769     
00770     /* Output whitening and unpacking. (900 bytes on i386) */
00771     OUTPACK(c,out,4);
00772     OUTPACK(d,out,5);
00773     OUTPACK(a,out,6);
00774     OUTPACK(b,out,7);
00775 }
00776 
00777 
00778 /* Decrypt one block.  in and out may be the same. */
00779 void TwoFishCipher::DecryptBlock(char *ibuf,char *obuf)
00780 {
00781     // Complete function; <800 bytes on i386. 
00782     
00783     unsigned char *in=(unsigned char*)ibuf;
00784     unsigned char *out=(unsigned char*)obuf;
00785     
00786     /* The four 32-bit chunks of the text. */
00787     uint32 a, b, c, d;
00788     
00789     /* Input whitening and packing. (160 bytes on i386) */
00790     INPACK(c,in,4);
00791     INPACK(d,in,5);
00792     INPACK(a,in,6);
00793     INPACK(b,in,7);
00794     
00795     /* Encryption Feistel cycles. (<500 bytes on i386) */
00796     register uint32 x,y;
00797     for(int i=31; i>=0; )
00798     {
00799         x=(this->c_s[0][ c        & 0xFF]) ^ 
00800           (this->c_s[1][(c >>  8) & 0xFF]) ^ 
00801           (this->c_s[2][(c >> 16) & 0xFF]) ^ 
00802           (this->c_s[3][ c >> 24        ]);
00803         y=(this->c_s[1][ d        & 0xFF]) ^ 
00804           (this->c_s[2][(d >>  8) & 0xFF]) ^ 
00805           (this->c_s[3][(d >> 16) & 0xFF]) ^ 
00806           (this->c_s[0][ d >> 24        ]);
00807         x += y;
00808         y += x; 
00809         b ^= y + this->c_k[i--]; 
00810         b  = (b >> 1) | (b << 31);
00811         a  = (a << 1) | (a >> 31);
00812         a ^= (x + this->c_k[i--]);
00813         
00814         x=(this->c_s[0][ a        & 0xFF]) ^ 
00815           (this->c_s[1][(a >>  8) & 0xFF]) ^ 
00816           (this->c_s[2][(a >> 16) & 0xFF]) ^ 
00817           (this->c_s[3][ a >> 24        ]);
00818         y=(this->c_s[1][ b &        0xFF]) ^ 
00819           (this->c_s[2][(b >>  8) & 0xFF]) ^ 
00820           (this->c_s[3][(b >> 16) & 0xFF]) ^ 
00821           (this->c_s[0][ b >> 24        ]);
00822         x += y;
00823         y += x;
00824         d ^= y + this->c_k[i--];
00825         d  = (d >> 1) | (d << 31);
00826         c  = (c << 1) | (c >> 31);
00827         c ^= (x + this->c_k[i--]);
00828     }
00829     
00830     /* Output whitening and unpacking. (750 bytes on i386) */
00831     OUTPACK(a,out,0);
00832     OUTPACK(b,out,1);
00833     OUTPACK(c,out,2);
00834     OUTPACK(d,out,3);
00835 }
00836 
00837 
00838 void TwoFishCipher::_reset()
00839 {
00840     uint32 *p,*pend;
00841     for(int i=0; i<4; i++)
00842         for(p=&(c_s[i][0]),pend=&(c_s[i][256]); p<pend; p++)
00843         {  *p=uint32(0U);  }
00844     for(p=&(c_w[0]),pend=&(c_w[8]); p<pend; p++)
00845     {  *p=uint32(0U);  }
00846     for(p=&(c_k[0]),pend=&(c_k[32]); p<pend; p++)
00847     {  *p=uint32(0U);  }
00848 }
00849 
00850 
00851 int TwoFishCipher::CopyFrom(BlockCipherBase *_from)
00852 {
00853     if(!_from || _from->GetPar()->cipher_ID!=par.cipher_ID)  return(-2);
00854     
00855     TwoFishCipher *from=(TwoFishCipher *)_from;
00856     for(int i=0; i<4; i++)
00857     {  memcpy(c_s[i],from->c_s[i],256*sizeof(uint32));  }
00858     memcpy(c_w,from->c_w,8*sizeof(uint32));
00859     memcpy(c_k,from->c_k,32*sizeof(uint32));
00860     
00861     return(0);
00862 }
00863 
00864 
00865 static const size_t twofish_par_kl[2]={16,32};
00866 
00867 const BlockCipherBase::Parameters TwoFishCipher::par = 
00868 {
00869     INIT_FIELD(block_size) 16,
00870     INIT_FIELD(n_key_lengths) 2,
00871     INIT_FIELD(key_length) twofish_par_kl,
00872     INIT_FIELD(cipher_ID) 0x2F15,
00873     INIT_FIELD(name) "twofish"
00874 };
00875 
00876 
00877 #if 0    /* SIMPLE FILE ENCRYPTION PROGRAM */
00878 
00879 #include <unistd.h>
00880 char *prg_name="test_twofish";
00881 int main()
00882 {
00883     size_t keylen=32;
00884     size_t blocksize=16;
00885     char buf[256*blocksize];
00886     
00887     /*{
00888         TwoFishCipher tfc;
00889         for(int i=0; i<1000; i++)
00890         {  tfc.SetKey("thisIsth3s3ct1tkEywitScHs967&&#",keylen);  }
00891     }*/
00892     
00893     TwoFishCipher tfc;
00894     fprintf(stderr,"setkey=%d\n",
00895         tfc.SetKey("thisIsth3s3ct1tkEywitScHs967&&#",keylen));
00896     
00897     for(;;)
00898     {
00899         int rd=read(0,buf,256*blocksize);
00900         if(rd<int(blocksize))  break;
00901         while(rd%blocksize) --rd;
00902         char *iob=buf,*endiob=&buf[rd];
00903         for(;iob<endiob;iob+=blocksize)
00904         {
00905             // Benchmark modus: encrypt & decrypt it. 
00906             tfc.EncryptBlock(iob,iob);
00907             tfc.DecryptBlock(iob,iob);
00908         }
00909         write(1,buf,rd);
00910     }
00911     
00912     return(0);
00913 }
00914 #endif

Generated on Sat Feb 19 22:33:45 2005 for Ray by doxygen 1.3.5