Initial revision
[silc.git] / lib / silccrypt / cast.c
1 /* Modified for SILC. -Pekka */\r
2 \r
3 /* This is an independent implementation of the encryption algorithm:   */\r
4 /*                                                                      */\r
5 /*         CAST-256 by Carlisle Adams of Entrust Tecnhologies           */\r
6 /*                                                                      */\r
7 /* which is a candidate algorithm in the Advanced Encryption Standard   */\r
8 /* programme of the US National Institute of Standards and Technology.  */\r
9 /*                                                                      */\r
10 /* Copyright in this implementation is held by Dr B R Gladman but I     */\r
11 /* hereby give permission for its free direct or derivative use subject */\r
12 /* to acknowledgment of its origin and compliance with any conditions   */\r
13 /* that the originators of the algorithm place on its exploitation.     */\r
14 /*                                                                      */\r
15 /* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999     */\r
16 \r
17 /* Timing data for CAST-256 (cast.c)\r
18 \r
19 Core timing without I/O endian conversion:\r
20 \r
21 128 bit key:\r
22 Key Setup:    4333 cycles\r
23 Encrypt:       633 cycles =    40.4 mbits/sec\r
24 Decrypt:       634 cycles =    40.4 mbits/sec\r
25 Mean:          634 cycles =    40.4 mbits/sec\r
26 \r
27 192 bit key:\r
28 Key Setup:    4342 cycles\r
29 Encrypt:       633 cycles =    40.4 mbits/sec\r
30 Decrypt:       633 cycles =    40.4 mbits/sec\r
31 Mean:          633 cycles =    40.4 mbits/sec\r
32 \r
33 256 bit key:\r
34 Key Setup:    4325 cycles\r
35 Encrypt:       639 cycles =    40.1 mbits/sec\r
36 Decrypt:       638 cycles =    40.1 mbits/sec\r
37 Mean:          639 cycles =    40.1 mbits/sec\r
38 \r
39 Full timing with I/O endian conversion:\r
40 \r
41 128 bit key:\r
42 Key Setup:    4294 cycles\r
43 Encrypt:       678 cycles =    37.8 mbits/sec\r
44 Decrypt:       669 cycles =    38.3 mbits/sec\r
45 Mean:          674 cycles =    38.0 mbits/sec\r
46 \r
47 192 bit key:\r
48 Key Setup:    4314 cycles\r
49 Encrypt:       678 cycles =    37.8 mbits/sec\r
50 Decrypt:       670 cycles =    38.2 mbits/sec\r
51 Mean:          674 cycles =    38.0 mbits/sec\r
52 \r
53 256 bit key:\r
54 Key Setup:    4313 cycles\r
55 Encrypt:       678 cycles =    37.8 mbits/sec\r
56 Decrypt:       669 cycles =    38.3 mbits/sec\r
57 Mean:          674 cycles =    38.0 mbits/sec\r
58 \r
59 */\r
60 \r
61 #include "silcincludes.h"\r
62 #include "cast.h"\r
63     \r
64 u4byte s_box[4][256] = \r
65 { {\r
66     0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9C004dd3, \r
67     0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,\r
68     0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, 0x28683b6f, 0xc07fd059, \r
69     0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,\r
70     0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, \r
71     0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, \r
72     0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, 0xb82cbaef, 0xd751d159, \r
73     0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,\r
74     0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f,\r
75     0xb48ee411, 0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,\r
76     0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0C50, 0x882240f2, 0x0c6e4f38, \r
77     0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,\r
78     0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, \r
79     0xe63d37e0, 0x2a54f6b3, 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, \r
80     0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb, \r
81     0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,\r
82     0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, \r
83     0xa0bebc3c, 0x54623779, 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6,\r
84     0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6C2, 0x81383f05, 0x6963c5c8,\r
85     0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,\r
86     0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, \r
87     0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e,\r
88     0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, 0x6b54bfab, 0x2b0b1426, \r
89     0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, \r
90     0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, \r
91     0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f,\r
92     0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, 0x7b5a41f0, 0xd37cfbad, \r
93     0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, \r
94     0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, \r
95     0x5ad328d8, 0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,\r
96     0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, 0x3f04442f, 0x6188b153, \r
97     0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, \r
98     0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, \r
99     0xdd24cb9e, 0x7e1c54bd, 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755,\r
100     0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, 0x580304f0, 0xca042cf1, \r
101     0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,\r
102     0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, \r
103     0xd5ea50f1, 0x85a92872, 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79,\r
104     0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814C, 0x474d6ad7, 0x7c0c5e5c, \r
105     0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,\r
106     0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, \r
107     0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, \r
108     0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf\r
109   },\r
110   {\r
111     0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a,\r
112     0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, \r
113     0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, 0xa0b52f7b, 0x59e83605, \r
114     0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,\r
115     0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, \r
116     0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, \r
117     0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, 0xe113c85b, 0xacc40083, \r
118     0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,\r
119     0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, \r
120     0x361e3084, 0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, \r
121     0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094, 0x2537a95e, \r
122     0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,\r
123     0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, \r
124     0x721d9bfd, 0xa58684bb, 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, \r
125     0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064, \r
126     0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,\r
127     0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, \r
128     0x83ca6b94, 0x2d6ed23b, 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, \r
129     0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364, \r
130     0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,\r
131     0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, \r
132     0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, \r
133     0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, 0xee41e729, 0x6e1d2d7c, \r
134     0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,\r
135     0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, \r
136     0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, \r
137     0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, 0xcdf0b680, 0x17844d3b, \r
138     0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,\r
139     0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, \r
140     0xef8579cc, 0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, \r
141     0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c, 0x80823028, \r
142     0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,\r
143     0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6,\r
144     0x273be979, 0xb0ffeaa6, 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, \r
145     0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1, \r
146     0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,\r
147     0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, \r
148     0x145892f5, 0x91584f7f, 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, \r
149     0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d, \r
150     0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,\r
151     0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, \r
152     0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, \r
153     0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1\r
154   },\r
155   {\r
156     0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b,\r
157     0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, \r
158     0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, 0x11107d9f, 0x07647db9,\r
159     0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,\r
160     0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd,\r
161     0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e,\r
162     0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, 0xa8c01db7, 0x579fc264,\r
163     0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,\r
164     0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, \r
165     0xc5884a28, 0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, \r
166     0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0, 0x1651192e, \r
167     0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,\r
168     0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, \r
169     0x796fb449, 0x8252dc15, 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, \r
170     0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e, \r
171     0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,\r
172     0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, \r
173     0x96bbb682, 0x93b4b148, 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, \r
174     0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240, \r
175     0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,\r
176     0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, \r
177     0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15,\r
178     0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, 0x68cc7bfb, 0xd90f2788, \r
179     0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,\r
180     0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, \r
181     0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, \r
182     0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, 0x285ba1c8, 0x3c62f44f, \r
183     0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,\r
184     0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, \r
185     0x12deca4d, 0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, \r
186     0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437, 0xec00c9a9, \r
187     0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,\r
188     0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, \r
189     0xa2e53f55, 0xb9e6d4bc, 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, \r
190     0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2, \r
191     0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,\r
192     0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, \r
193     0xf1ac2571, 0xcc8239c2, 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, \r
194     0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d, \r
195     0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,\r
196     0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, \r
197     0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, \r
198     0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783\r
199   },\r
200   { \r
201     0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, \r
202     0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, \r
203     0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, 0x28147f5f, 0x4fa2b8cd, \r
204     0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,\r
205     0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, \r
206     0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, \r
207     0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, 0xce84ffdf, 0xf5718801, \r
208     0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,\r
209     0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, \r
210     0x72500e03, 0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,\r
211     0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805, 0x7f3d5ce3, \r
212     0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,\r
213     0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c,\r
214     0x18f8931e, 0x281658e6, 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c,\r
215     0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16, \r
216     0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,\r
217     0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7,\r
218     0x0ce5c2ec, 0x4db4bba6, 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, \r
219     0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002, \r
220     0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,\r
221     0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, \r
222     0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, \r
223     0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, 0x026a4ceb, 0x52437eff, \r
224     0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,\r
225     0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, \r
226     0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, \r
227     0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, 0x63315c21, 0x5e0a72ec, \r
228     0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,\r
229     0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, \r
230     0xcfcbd12f, 0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, \r
231     0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532, 0x58fd7eb6,\r
232     0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,\r
233     0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, \r
234     0xaf9eb3db, 0x29c9ed2a, 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, \r
235     0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6, \r
236     0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,\r
237     0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2,\r
238     0xf3e0eb5b, 0xd6cc9876, 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, \r
239     0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda,\r
240     0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,\r
241     0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6,\r
242     0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e,\r
243     0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2\r
244   }\r
245 };\r
246 \r
247 #define f1(y,x,kr,km)           \\r
248     t  = rotl(km + x, kr);      \\r
249     u  = s_box[0][byte(t,3)];   \\r
250     u ^= s_box[1][byte(t,2)];   \\r
251     u -= s_box[2][byte(t,1)];   \\r
252     u += s_box[3][byte(t,0)];   \\r
253     y ^= u\r
254 \r
255 #define f2(y,x,kr,km)           \\r
256     t  = rotl(km ^ x, kr);      \\r
257     u  = s_box[0][byte(t,3)];   \\r
258     u -= s_box[1][byte(t,2)];   \\r
259     u += s_box[2][byte(t,1)];   \\r
260     u ^= s_box[3][byte(t,0)];   \\r
261     y ^= u\r
262 \r
263 #define f3(y,x,kr,km)           \\r
264     t  = rotl(km - x, kr);      \\r
265     u  = s_box[0][byte(t,3)];   \\r
266     u += s_box[1][byte(t,2)];   \\r
267     u ^= s_box[2][byte(t,1)];   \\r
268     u -= s_box[3][byte(t,0)];   \\r
269     y ^= u\r
270 \r
271 #define f_rnd(x,n)                              \\r
272     f1(x[2],x[3],l_key[n],    l_key[n + 4]);    \\r
273     f2(x[1],x[2],l_key[n + 1],l_key[n + 5]);    \\r
274     f3(x[0],x[1],l_key[n + 2],l_key[n + 6]);    \\r
275     f1(x[3],x[0],l_key[n + 3],l_key[n + 7])\r
276 \r
277 #define i_rnd(x, n)                             \\r
278     f1(x[3],x[0],l_key[n + 3],l_key[n + 7]);    \\r
279     f3(x[0],x[1],l_key[n + 2],l_key[n + 6]);    \\r
280     f2(x[1],x[2],l_key[n + 1],l_key[n + 5]);    \\r
281     f1(x[2],x[3],l_key[n],    l_key[n + 4])\r
282 \r
283 #define k_rnd(k,tr,tm)          \\r
284     f1(k[6],k[7],tr[0],tm[0]);  \\r
285     f2(k[5],k[6],tr[1],tm[1]);  \\r
286     f3(k[4],k[5],tr[2],tm[2]);  \\r
287     f1(k[3],k[4],tr[3],tm[3]);  \\r
288     f2(k[2],k[3],tr[4],tm[4]);  \\r
289     f3(k[1],k[2],tr[5],tm[5]);  \\r
290     f1(k[0],k[1],tr[6],tm[6]);  \\r
291     f2(k[7],k[0],tr[7],tm[7])\r
292 \r
293 /* initialise the key schedule from the user supplied key   */\r
294 \r
295 u4byte *cast_set_key(CastContext *ctx,\r
296                      const u4byte in_key[], const u4byte key_len)\r
297 {   \r
298     u4byte  i, j, t, u, cm, cr, lk[8], tm[8], tr[8];\r
299     u4byte *l_key = ctx->l_key;\r
300 \r
301     for(i = 0; i < key_len / 32; ++i)\r
302 \r
303         lk[i] = io_swap(in_key[i]);\r
304 \r
305     for(; i < 8; ++i)\r
306 \r
307         lk[i] = 0;\r
308 \r
309     cm = 0x5a827999; cr = 19;\r
310 \r
311     for(i = 0; i < 96; i += 8)\r
312     {\r
313         for(j = 0; j < 8; ++j)\r
314         {\r
315             tm[j] = cm; cm += 0x6ed9eba1;\r
316             tr[j] = cr; cr += 17;\r
317         }\r
318 \r
319         k_rnd(lk, tr, tm);\r
320         \r
321         for(j = 0; j < 8; ++j)\r
322         {\r
323             tm[j] = cm; cm += 0x6ed9eba1;\r
324             tr[j] = cr; cr += 17;\r
325         }\r
326 \r
327         k_rnd(lk, tr, tm);\r
328 \r
329         l_key[i + 0] = lk[0]; l_key[i + 1] = lk[2];\r
330         l_key[i + 2] = lk[4]; l_key[i + 3] = lk[6];\r
331         l_key[i + 4] = lk[7]; l_key[i + 5] = lk[5];\r
332         l_key[i + 6] = lk[3]; l_key[i + 7] = lk[1];\r
333     }\r
334 \r
335     return l_key;\r
336 };\r
337 \r
338 /* encrypt a block of text  */\r
339 \r
340 void cast_encrypt(CastContext *ctx,\r
341                   const u4byte in_blk[4], u4byte out_blk[])\r
342 {   \r
343     u4byte  t, u, blk[4];\r
344     u4byte *l_key = ctx->l_key;\r
345 \r
346     blk[0] = io_swap(in_blk[0]); blk[1] = io_swap(in_blk[1]);\r
347     blk[2] = io_swap(in_blk[2]); blk[3] = io_swap(in_blk[3]);\r
348 \r
349     f_rnd(blk,  0); f_rnd(blk,  8);\r
350     f_rnd(blk, 16); f_rnd(blk, 24);\r
351     f_rnd(blk, 32); f_rnd(blk, 40);\r
352     i_rnd(blk, 48); i_rnd(blk, 56);\r
353     i_rnd(blk, 64); i_rnd(blk, 72);\r
354     i_rnd(blk, 80); i_rnd(blk, 88);\r
355 \r
356     out_blk[0] = io_swap(blk[0]); out_blk[1] = io_swap(blk[1]);\r
357     out_blk[2] = io_swap(blk[2]); out_blk[3] = io_swap(blk[3]);\r
358 };\r
359 \r
360 /* decrypt a block of text  */\r
361 \r
362 void cast_decrypt(CastContext *ctx,\r
363                   const u4byte in_blk[4], u4byte out_blk[4])\r
364 {   \r
365     u4byte  t, u, blk[4];\r
366     u4byte *l_key = ctx->l_key;\r
367 \r
368     blk[0] = io_swap(in_blk[0]); blk[1] = io_swap(in_blk[1]);\r
369     blk[2] = io_swap(in_blk[2]); blk[3] = io_swap(in_blk[3]);\r
370 \r
371     f_rnd(blk, 88); f_rnd(blk, 80);\r
372     f_rnd(blk, 72); f_rnd(blk, 64);\r
373     f_rnd(blk, 56); f_rnd(blk, 48);\r
374     i_rnd(blk, 40); i_rnd(blk, 32);\r
375     i_rnd(blk, 24); i_rnd(blk, 16);\r
376     i_rnd(blk,  8); i_rnd(blk,  0);\r
377 \r
378     out_blk[0] = io_swap(blk[0]); out_blk[1] = io_swap(blk[1]);\r
379     out_blk[2] = io_swap(blk[2]); out_blk[3] = io_swap(blk[3]);\r
380 };\r
381 \r