a3b1889b72c0bdc65cb50f87ca2154e4d5b5a504
[openssl.git] / crypto / camellia / camellia.c
1 /* crypto/camellia/camellia.c -*- mode:C; c-file-style: "eay" -*- */
2 /* ====================================================================
3  * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . 
4  * ALL RIGHTS RESERVED.
5  *
6  * Intellectual Property information for Camellia:
7  *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
8  *
9  * News Release for Announcement of Camellia open source:
10  *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
11  *
12  * The Camellia Code included herein is developed by
13  * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
14  * to the OpenSSL project.
15  *
16  * The Camellia Code is licensed pursuant to the OpenSSL open source
17  * license provided below.
18  */
19 /* ====================================================================
20  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  *
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer. 
28  *
29  * 2. Redistributions in binary form must reproduce the above copyright
30  *    notice, this list of conditions and the following disclaimer in
31  *    the documentation and/or other materials provided with the
32  *    distribution.
33  *
34  * 3. All advertising materials mentioning features or use of this
35  *    software must display the following acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
38  *
39  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
40  *    endorse or promote products derived from this software without
41  *    prior written permission. For written permission, please contact
42  *    openssl-core@openssl.org.
43  *
44  * 5. Products derived from this software may not be called "OpenSSL"
45  *    nor may "OpenSSL" appear in their names without prior written
46  *    permission of the OpenSSL Project.
47  *
48  * 6. Redistributions of any form whatsoever must retain the following
49  *    acknowledgment:
50  *    "This product includes software developed by the OpenSSL Project
51  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
54  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
57  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
62  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
64  * OF THE POSSIBILITY OF SUCH DAMAGE.
65  * ====================================================================
66  */
67
68 /* Algorithm Specification 
69    http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
70 */
71
72 #include "camellia.h"
73 #include "cmll_locl.h"
74 #include <string.h>
75 #include <stdlib.h>
76
77 /* These macro variables select what code is used in the creation of 
78    the Camellia library objects */
79
80 #define USE_C_FEISTEL_CODE  0 /* Set to 1 to use C code, 0 to inline via macro */
81
82 /* Word rotation */
83 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
84 #define RightRotate(x, s) _lrotr(x, s)
85 #define LeftRotate(x, s) _lrotl(x, s)
86 #elif defined(__INTEL__) && defined(__MWERKS__)
87 #define RightRotate(x, s) __ror(x, s)
88 #define LeftRotate(x, s) __rol(x, s)
89 #else
90 #define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) )
91 #define LeftRotate(x, s) ( ((x) << (s)) + ((x) >> (32 - s)) )
92 #endif
93
94
95 /* S-box data */
96 const Word SBOX1_1110[] = 
97 {
98     0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 
99     0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 
100     0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, 
101     0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, 
102     0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 
103     0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 
104     0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, 
105     0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, 
106     0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 
107     0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 
108     0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, 
109     0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, 
110     0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 
111     0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 
112     0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, 
113     0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, 
114     0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 
115     0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 
116     0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, 
117     0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, 
118     0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 
119     0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 
120     0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, 
121     0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, 
122     0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 
123     0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 
124     0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, 
125     0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, 
126     0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 
127     0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 
128     0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, 
129     0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, 
130     0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 
131     0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 
132     0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, 
133     0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, 
134     0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 
135     0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 
136     0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, 
137     0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, 
138     0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 
139     0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 
140     0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00
141 };
142 const Word SBOX4_4404[] = 
143 {
144     0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 
145     0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 
146     0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, 
147     0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, 
148     0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 
149     0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 
150     0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, 
151     0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, 
152     0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 
153     0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 
154     0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, 
155     0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, 
156     0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 
157     0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 
158     0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, 
159     0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, 
160     0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 
161     0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 
162     0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, 
163     0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, 
164     0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 
165     0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 
166     0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, 
167     0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, 
168     0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 
169     0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 
170     0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, 
171     0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, 
172     0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 
173     0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 
174     0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, 
175     0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, 
176     0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 
177     0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 
178     0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, 
179     0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, 
180     0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 
181     0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 
182     0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, 
183     0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, 
184     0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 
185     0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 
186     0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e
187 };
188 const Word SBOX2_0222[] = 
189 {
190     0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 
191     0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 
192     0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, 
193     0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, 
194     0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 
195     0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 
196     0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, 
197     0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, 
198     0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 
199     0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 
200     0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, 
201     0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, 
202     0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 
203     0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 
204     0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, 
205     0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, 
206     0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 
207     0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 
208     0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, 
209     0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, 
210     0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 
211     0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 
212     0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, 
213     0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, 
214     0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 
215     0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 
216     0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, 
217     0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, 
218     0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 
219     0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 
220     0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, 
221     0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, 
222     0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 
223     0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 
224     0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, 
225     0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, 
226     0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 
227     0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 
228     0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, 
229     0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, 
230     0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 
231     0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 
232     0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d
233 };
234 const Word SBOX3_3033[] = 
235 {
236     0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 
237     0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 
238     0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, 
239     0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, 
240     0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 
241     0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 
242     0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, 
243     0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, 
244     0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 
245     0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 
246     0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, 
247     0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, 
248     0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 
249     0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 
250     0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, 
251     0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, 
252     0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 
253     0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 
254     0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, 
255     0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, 
256     0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 
257     0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 
258     0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, 
259     0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, 
260     0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 
261     0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 
262     0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, 
263     0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, 
264     0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 
265     0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 
266     0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, 
267     0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, 
268     0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 
269     0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 
270     0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, 
271     0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, 
272     0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 
273     0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 
274     0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, 
275     0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, 
276     0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 
277     0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 
278     0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f
279 };
280
281 #define CopyConvertEndianness16in(src, dst) \
282 do {\
283     (dst)[0] = GETU32((Byte *)(src));\
284     (dst)[1] = GETU32((Byte *)(src) +  4);\
285     (dst)[2] = GETU32((Byte *)(src) +  8);\
286     (dst)[3] = GETU32((Byte *)(src) + 12);\
287 } while(0)
288 #define CopyConvertEndianness16out(src, dst) \
289 do{\
290     PUTU32(dst     ,(src)[0]);\
291     PUTU32(dst +  4,(src)[1]);\
292     PUTU32(dst +  8,(src)[2]);\
293     PUTU32(dst + 12,(src)[3]);\
294 }while(0)
295
296 /* Computes the exclusive-or of x and y and assigns it to z, ie,
297  * z = x ^ y */
298 #define XorBlock(x, y, z)\
299 do {\
300     (z)[0] = (x)[0] ^ (y)[0];\
301     (z)[1] = (x)[1] ^ (y)[1];\
302     (z)[2] = (x)[2] ^ (y)[2];\
303     (z)[3] = (x)[3] ^ (y)[3];\
304 } while(0)
305
306 /* Transforms an array of 4 words by flipping the first two words 
307  * with the last 2 words. */
308 #define SwapHalf(x)\
309 do {\
310     Word _t;\
311     _t   = (x)[0];\
312     (x)[0] = (x)[2];\
313     (x)[2] = _t;\
314     _t   = (x)[1];\
315     (x)[1] = (x)[3];\
316     (x)[3] = _t;\
317 } while(0)
318
319 /* This function is only used in key generation. */
320 static void RotBlock(const Word x[], const int n, Word y[])
321 {
322  int r = (n & 31);   /* Must not be 0 */
323  int idx = (n >> 5);
324  int idx1 = (idx + 1) & 3;
325  int idx2 = (idx1 + 1) & 3;
326         
327  y[0] = (x[idx] << r) | (x[idx1] >> (32 - r));
328  y[1] = (x[idx1] << r) | (x[idx2] >> (32 - r));
329 }
330
331
332 /* The phi algorithm given in C.2.7 of the Camellia spec document. */
333 #if (USE_C_FEISTEL_CODE)
334 static void Camellia_Feistel(Word *x, const Word *k, const int key_offset)
335         {
336         Word D, U;
337         Word s1, s2;
338
339         s1 = x[0] ^ k[0];
340         U  = SBOX4_4404[(Byte)s1];
341         U ^= SBOX3_3033[(Byte)(s1 >> 8)];
342         U ^= SBOX2_0222[(Byte)(s1 >> 16)];
343         U ^= SBOX1_1110[(Byte)(s1 >> 24)];
344         s2 = x[1] ^ k[1];
345         D  = SBOX1_1110[(Byte)s2];
346         D ^= SBOX4_4404[(Byte)(s2 >> 8)];
347         D ^= SBOX3_3033[(Byte)(s2 >> 16)];
348         D ^= SBOX2_0222[(Byte)(s2 >> 24)];
349
350         x[2] ^= D ^ U;
351         x[3] ^= D ^ U ^ RightRotate(U, 8);
352
353         s1 = x[2] ^ k[key_offset];
354         U = SBOX4_4404[(Byte)s1];
355         U ^= SBOX3_3033[(Byte)(s1 >> 8)];
356         U ^= SBOX2_0222[(Byte)(s1 >> 16)];
357         U ^= SBOX1_1110[(Byte)(s1 >> 24)];
358         s2 = x[3] ^ k[key_offset+1];
359         D = SBOX1_1110[(Byte)s2];
360         D ^= SBOX4_4404[(Byte)(s2 >> 8)];
361         D ^= SBOX3_3033[(Byte)(s2 >> 16)];
362         D ^= SBOX2_0222[(Byte)(s2 >> 24)];
363
364         x[0] ^= D ^ U;
365         x[1] ^= D ^ U ^ RightRotate(U, 8);
366         }
367
368 #else /* use macro code. Slower on PC due to code/cache interaction */
369
370 #define Camellia_Feistel(xx,kk,oo)\
371 do {\
372     Word * const _x = (Word *)(xx);\
373     const Word * const _k = (Word *)(kk);\
374     Word _D, _U;\
375     Word _s1, _s2;\
376 \
377     _s1 = _x[0] ^ _k[0];\
378     _U = SBOX4_4404[(Byte)_s1];\
379     _U ^= SBOX3_3033[(Byte)(_s1 >> 8)];\
380     _U ^= SBOX2_0222[(Byte)(_s1 >> 16)];\
381     _U ^= SBOX1_1110[(Byte)(_s1 >> 24)];\
382     _s2 = _x[1] ^ _k[1];\
383     _D = SBOX1_1110[(Byte)_s2];\
384     _D ^= SBOX4_4404[(Byte)(_s2 >> 8)];\
385     _D ^= SBOX3_3033[(Byte)(_s2 >> 16)];\
386     _D ^= SBOX2_0222[(Byte)(_s2 >> 24)];\
387 \
388     _x[2] ^= _D ^ _U;\
389     _x[3] ^= _D ^ _U ^ RightRotate(_U, 8);\
390 \
391     _s1 = _x[2] ^ _k[oo];\
392     _U = SBOX4_4404[(Byte)_s1];\
393     _U ^= SBOX3_3033[(Byte)(_s1 >> 8)];\
394     _U ^= SBOX2_0222[(Byte)(_s1 >> 16)];\
395     _U ^= SBOX1_1110[(Byte)(_s1 >> 24)];\
396     _s2 = _x[3] ^ _k[(oo)+1];\
397     _D = SBOX1_1110[(Byte)_s2];\
398     _D ^= SBOX4_4404[(Byte)(_s2 >> 8)];\
399     _D ^= SBOX3_3033[(Byte)(_s2 >> 16)];\
400     _D ^= SBOX2_0222[(Byte)(_s2 >> 24)];\
401 \
402     _x[0] ^= _D ^ _U;\
403     _x[1] ^= _D ^ _U ^ RightRotate(_U, 8);\
404 } while(0)
405
406 #endif /* USE_C_FEISTEL_CODE */
407
408
409 /* Key generation constants */
410
411 const Word SIGMA[] = {
412     0xa09e667f, 0x3bcc908b,
413     0xb67ae858, 0x4caa73b2,
414     0xc6ef372f, 0xe94f82be,
415     0x54ff53a5, 0xf1d36f1c,
416     0x10e527fa, 0xde682d1d,
417     0xb05688c2, 0xb3e6c1fd
418 };
419
420 const int KSFT1[26] = {
421     0, 64, 0, 64, 15, 79, 15, 79, 30, 94, 45, 109, 45, 124, 60, 124, 77, 13,
422     94, 30, 94, 30, 111, 47, 111, 47 
423 };
424
425 const int KIDX1[26] = {
426     0, 0, 8, 8, 0, 0, 8, 8, 8, 8, 0, 0, 8, 0, 8, 8, 0, 0, 0, 0, 8, 8, 0, 0, 8, 8 
427 };
428
429 const int KSFT2[34] = {
430     0, 64, 0, 64, 15, 79, 15, 79, 30, 94, 30, 94, 45, 109, 45, 109, 60, 124, 
431     60, 124, 60, 124, 77, 13, 77, 13, 94, 30, 94, 30, 111, 47, 111, 47 
432 };
433
434 const int KIDX2[34] = {
435     0, 0, 12, 12, 4, 4, 8, 8, 4, 4, 12, 12, 0, 0, 8, 8, 0, 0, 4, 4, 12, 12, 
436     0, 0, 8, 8, 4, 4, 8, 8, 0, 0, 12, 12 
437 };
438
439
440 /* Generates the key table e from rawKey. The reference implementation has been
441  * mangled to avoid the necessity of having to separately code the Feistel function. */
442 void Camellia_Ekeygen(const int keyBitLength, const Byte *rawKey, KEY_TABLE_TYPE keyTable)
443         {
444         Word t[16];
445         int  i;
446
447
448         /* Copy raw key material into the key table. Keep the bytes register- */
449         /* endian-correct (ie. bytes appear in registers in the correct order */
450         /* but will appear reversed in memory on a little-endian machine      */
451         if (keyBitLength == 128)
452                 {
453                 CopyConvertEndianness16in((Word *)rawKey, (Word *)t);
454                 for (i = 4; i < 8; i++)
455                         t[i] = 0;
456                 }
457         else if (keyBitLength == 192)
458                 {
459                 CopyConvertEndianness16in((Word *)rawKey, (Word *)t);
460                 for (i =  4; i < 6; i++)
461                         {
462                         Word tmp = (rawKey[4*i] << 24) | (rawKey[4*i+1] << 16) | 
463                                 (rawKey[4*i+2] << 8) | (rawKey[4*i+3] << 0);
464                         t[i] = tmp;
465                         t[i+2] = ~tmp;
466                         }
467                 }
468         else if (keyBitLength == 256)
469                 {
470                 CopyConvertEndianness16in((Word *)rawKey, (Word *)t);
471                 CopyConvertEndianness16in(((Word *)rawKey)+4, ((Word *)t)+4);
472                 }
473
474         /* Use the Feistel routine to scramble the key material */
475         XorBlock(t, t+4, t+8);
476         Camellia_Feistel(t+8, SIGMA, 2);
477         XorBlock(t+8, t, t+8);
478         Camellia_Feistel(t+8, SIGMA+4,2);
479  
480         /* Fill the keyTable. Requires many block rotations. */
481         if (keyBitLength == 128)
482                 {
483                 memcpy(keyTable, t, 16);
484                 memcpy(keyTable+4, t+8, 16);
485                 for (i = 4; i < 26; i += 2 )
486                         {
487                         RotBlock(t + KIDX1[i + 0], KSFT1[i + 0], keyTable+i*2);
488                         RotBlock(t + KIDX1[i + 1], KSFT1[i + 1], keyTable+i*2+2);
489                         }
490                 }
491         else
492                 {
493                 XorBlock(t+8, t+4, t+12);
494                 Camellia_Feistel(t+12, SIGMA+8,2);
495                 memcpy(keyTable, t, 16);
496                 memcpy(keyTable+4, t+12, 16);
497                 for (i = 4; i < 34; i += 2)
498                         {
499                         RotBlock(t + KIDX2[i + 0], KSFT2[i + 0], keyTable+i*2);
500                         RotBlock(t + KIDX2[i + 1], KSFT2[i + 1], keyTable+i*2+2);
501                         }
502                 }
503
504         }
505
506
507 /* Described in great length in the accompanying document. */
508 void Camellia_EncryptBlock(const int keyBitLength, const Byte plaintext[], 
509                 const KEY_TABLE_TYPE keyTable, Byte ciphertext[])
510         {
511         int j;
512         int grandRounds;
513
514         int totalGrandRounds = (keyBitLength == 128)? 3 : 4;
515         Word status[4]; 
516         int flayerLimit = totalGrandRounds - 1;
517         const Word *k = keyTable+4; 
518
519         /* Copy over plaintext to a ciphertext buffer */
520         CopyConvertEndianness16in(plaintext, status);
521
522         /* Encrypt plaintext block via multiple Feistel rounds */
523
524         XorBlock(status, keyTable, status);
525
526
527         for (grandRounds = 0; grandRounds < totalGrandRounds; grandRounds++)
528                 {
529                 /* Camellia makes 6 Feistel rounds */
530                 for (j = 0; j < 6; j+=2, k += 4)
531                         Camellia_Feistel(status,k,2);
532
533                 if (grandRounds < flayerLimit)
534                         {
535                         /* This is the same function as the diffusion function D of 
536                          * the accompanying documentation. See section 3.2 of the 
537                          * accompanying documentation for properties of the FLlayer function. */
538                         status[1] ^= LeftRotate(status[0] & k[0], 1);
539                         status[0] ^= status[1] | k[1];
540                         status[2] ^= status[3] | k[3];
541                         status[3] ^= LeftRotate(status[2] & k[2], 1);
542                         k += 4;
543                         }
544                 }
545
546         /* Apply the permutation function Pi1. Since Pi1 uses the key words in ascending 
547          * order it is necessary when decrypting to decrement the key word ptr again. */
548         SwapHalf(status);
549         XorBlock(status, k, status);
550
551         /* Convert endianness if needed and copy out to output array */
552         CopyConvertEndianness16out(status, ciphertext);
553
554         }
555
556 /* Described in great length in the accompanying document. */
557 void Camellia_DecryptBlock(const int keyBitLength, const Byte ciphertext[], 
558                 const KEY_TABLE_TYPE keyTable, Byte plaintext[])
559         {
560         int grandRounds;
561         int flayerLimit;
562         int totalGrandRounds;
563         int keyTableOffset;
564         int j;
565         const Word *k; 
566         Word status[4]; 
567
568         if (keyBitLength == 128)
569                 {
570                 totalGrandRounds = 3;
571                 keyTableOffset = 48;
572                 }
573         else
574                 {
575                 totalGrandRounds = 4;
576                 keyTableOffset = 64;
577                 }
578         k = keyTable+keyTableOffset;
579         flayerLimit = totalGrandRounds - 1;
580  
581         /* Copy over cipher text to a Word aligned buffer */
582         CopyConvertEndianness16in(ciphertext, status);
583
584         /* Decrypt ciphertext block */
585         XorBlock(status, k, status);
586         k -= 2;
587
588         for (grandRounds = 0; grandRounds < totalGrandRounds; grandRounds++)
589                 {
590                 /* Camellia makes 6 Feistel rounds */
591                 for (j = 0; j < 6; j+=2, k -= 4)
592                         Camellia_Feistel(status,k,-2);
593
594                 if (grandRounds < flayerLimit)
595                         {
596                         /* This is the same function as the diffusion function D of
597                          * the accompanying documentation. See section 3.2 of the 
598                          * accompanying documentation for properties of the FLlayer function. */
599                         status[1] ^= LeftRotate(status[0] & k[0], 1);
600                         status[0] ^= status[1] | k[1];
601                         status[2] ^= status[3] | k[-1];
602                         status[3] ^= LeftRotate(status[2] & k[-2], 1);
603                         k -= 4;
604                         }
605                 }
606
607         /* Apply the permutation function Pi1. Since Pi1 uses the key words in ascending 
608          * order it is necessary when decrypting to decrement the key word ptr again. */
609         k -= 2;
610         SwapHalf(status);
611         XorBlock(status, k, status);
612
613         /* Convert endianness if needed and copy out to output array */
614         CopyConvertEndianness16out(status, plaintext);
615         
616         }
617