/*
This code is written by kerukuro for cppcrypto library (http://cppcrypto.sourceforge.net/)
and released into public domain.
*/

/* Adapted for VeraCrypt */


#include "Camellia.h"
#include "Common/Endian.h"
#include "Crypto/misc.h"



//#define CPPCRYPTO_DEBUG

	static const uint64 S[8][256] = {
		{
			0x7070700070000070, 0x8282820082000082, 0x2c2c2c002c00002c, 0xececec00ec0000ec, 0xb3b3b300b30000b3, 0x2727270027000027, 0xc0c0c000c00000c0, 0xe5e5e500e50000e5,
			0xe4e4e400e40000e4, 0x8585850085000085, 0x5757570057000057, 0x3535350035000035, 0xeaeaea00ea0000ea, 0x0c0c0c000c00000c, 0xaeaeae00ae0000ae, 0x4141410041000041,
			0x2323230023000023, 0xefefef00ef0000ef, 0x6b6b6b006b00006b, 0x9393930093000093, 0x4545450045000045, 0x1919190019000019, 0xa5a5a500a50000a5, 0x2121210021000021,
			0xededed00ed0000ed, 0x0e0e0e000e00000e, 0x4f4f4f004f00004f, 0x4e4e4e004e00004e, 0x1d1d1d001d00001d, 0x6565650065000065, 0x9292920092000092, 0xbdbdbd00bd0000bd,
			0x8686860086000086, 0xb8b8b800b80000b8, 0xafafaf00af0000af, 0x8f8f8f008f00008f, 0x7c7c7c007c00007c, 0xebebeb00eb0000eb, 0x1f1f1f001f00001f, 0xcecece00ce0000ce,
			0x3e3e3e003e00003e, 0x3030300030000030, 0xdcdcdc00dc0000dc, 0x5f5f5f005f00005f, 0x5e5e5e005e00005e, 0xc5c5c500c50000c5, 0x0b0b0b000b00000b, 0x1a1a1a001a00001a,
			0xa6a6a600a60000a6, 0xe1e1e100e10000e1, 0x3939390039000039, 0xcacaca00ca0000ca, 0xd5d5d500d50000d5, 0x4747470047000047, 0x5d5d5d005d00005d, 0x3d3d3d003d00003d,
			0xd9d9d900d90000d9, 0x0101010001000001, 0x5a5a5a005a00005a, 0xd6d6d600d60000d6, 0x5151510051000051, 0x5656560056000056, 0x6c6c6c006c00006c, 0x4d4d4d004d00004d,
			0x8b8b8b008b00008b, 0x0d0d0d000d00000d, 0x9a9a9a009a00009a, 0x6666660066000066, 0xfbfbfb00fb0000fb, 0xcccccc00cc0000cc, 0xb0b0b000b00000b0, 0x2d2d2d002d00002d,
			0x7474740074000074, 0x1212120012000012, 0x2b2b2b002b00002b, 0x2020200020000020, 0xf0f0f000f00000f0, 0xb1b1b100b10000b1, 0x8484840084000084, 0x9999990099000099,
			0xdfdfdf00df0000df, 0x4c4c4c004c00004c, 0xcbcbcb00cb0000cb, 0xc2c2c200c20000c2, 0x3434340034000034, 0x7e7e7e007e00007e, 0x7676760076000076, 0x0505050005000005,
			0x6d6d6d006d00006d, 0xb7b7b700b70000b7, 0xa9a9a900a90000a9, 0x3131310031000031, 0xd1d1d100d10000d1, 0x1717170017000017, 0x0404040004000004, 0xd7d7d700d70000d7,
			0x1414140014000014, 0x5858580058000058, 0x3a3a3a003a00003a, 0x6161610061000061, 0xdedede00de0000de, 0x1b1b1b001b00001b, 0x1111110011000011, 0x1c1c1c001c00001c,
			0x3232320032000032, 0x0f0f0f000f00000f, 0x9c9c9c009c00009c, 0x1616160016000016, 0x5353530053000053, 0x1818180018000018, 0xf2f2f200f20000f2, 0x2222220022000022,
			0xfefefe00fe0000fe, 0x4444440044000044, 0xcfcfcf00cf0000cf, 0xb2b2b200b20000b2, 0xc3c3c300c30000c3, 0xb5b5b500b50000b5, 0x7a7a7a007a00007a, 0x9191910091000091,
			0x2424240024000024, 0x0808080008000008, 0xe8e8e800e80000e8, 0xa8a8a800a80000a8, 0x6060600060000060, 0xfcfcfc00fc0000fc, 0x6969690069000069, 0x5050500050000050,
			0xaaaaaa00aa0000aa, 0xd0d0d000d00000d0, 0xa0a0a000a00000a0, 0x7d7d7d007d00007d, 0xa1a1a100a10000a1, 0x8989890089000089, 0x6262620062000062, 0x9797970097000097,
			0x5454540054000054, 0x5b5b5b005b00005b, 0x1e1e1e001e00001e, 0x9595950095000095, 0xe0e0e000e00000e0, 0xffffff00ff0000ff, 0x6464640064000064, 0xd2d2d200d20000d2,
			0x1010100010000010, 0xc4c4c400c40000c4, 0x0000000000000000, 0x4848480048000048, 0xa3a3a300a30000a3, 0xf7f7f700f70000f7, 0x7575750075000075, 0xdbdbdb00db0000db,
			0x8a8a8a008a00008a, 0x0303030003000003, 0xe6e6e600e60000e6, 0xdadada00da0000da, 0x0909090009000009, 0x3f3f3f003f00003f, 0xdddddd00dd0000dd, 0x9494940094000094,
			0x8787870087000087, 0x5c5c5c005c00005c, 0x8383830083000083, 0x0202020002000002, 0xcdcdcd00cd0000cd, 0x4a4a4a004a00004a, 0x9090900090000090, 0x3333330033000033,
			0x7373730073000073, 0x6767670067000067, 0xf6f6f600f60000f6, 0xf3f3f300f30000f3, 0x9d9d9d009d00009d, 0x7f7f7f007f00007f, 0xbfbfbf00bf0000bf, 0xe2e2e200e20000e2,
			0x5252520052000052, 0x9b9b9b009b00009b, 0xd8d8d800d80000d8, 0x2626260026000026, 0xc8c8c800c80000c8, 0x3737370037000037, 0xc6c6c600c60000c6, 0x3b3b3b003b00003b,
			0x8181810081000081, 0x9696960096000096, 0x6f6f6f006f00006f, 0x4b4b4b004b00004b, 0x1313130013000013, 0xbebebe00be0000be, 0x6363630063000063, 0x2e2e2e002e00002e,
			0xe9e9e900e90000e9, 0x7979790079000079, 0xa7a7a700a70000a7, 0x8c8c8c008c00008c, 0x9f9f9f009f00009f, 0x6e6e6e006e00006e, 0xbcbcbc00bc0000bc, 0x8e8e8e008e00008e,
			0x2929290029000029, 0xf5f5f500f50000f5, 0xf9f9f900f90000f9, 0xb6b6b600b60000b6, 0x2f2f2f002f00002f, 0xfdfdfd00fd0000fd, 0xb4b4b400b40000b4, 0x5959590059000059,
			0x7878780078000078, 0x9898980098000098, 0x0606060006000006, 0x6a6a6a006a00006a, 0xe7e7e700e70000e7, 0x4646460046000046, 0x7171710071000071, 0xbababa00ba0000ba,
			0xd4d4d400d40000d4, 0x2525250025000025, 0xababab00ab0000ab, 0x4242420042000042, 0x8888880088000088, 0xa2a2a200a20000a2, 0x8d8d8d008d00008d, 0xfafafa00fa0000fa,
			0x7272720072000072, 0x0707070007000007, 0xb9b9b900b90000b9, 0x5555550055000055, 0xf8f8f800f80000f8, 0xeeeeee00ee0000ee, 0xacacac00ac0000ac, 0x0a0a0a000a00000a,
			0x3636360036000036, 0x4949490049000049, 0x2a2a2a002a00002a, 0x6868680068000068, 0x3c3c3c003c00003c, 0x3838380038000038, 0xf1f1f100f10000f1, 0xa4a4a400a40000a4,
			0x4040400040000040, 0x2828280028000028, 0xd3d3d300d30000d3, 0x7b7b7b007b00007b, 0xbbbbbb00bb0000bb, 0xc9c9c900c90000c9, 0x4343430043000043, 0xc1c1c100c10000c1,
			0x1515150015000015, 0xe3e3e300e30000e3, 0xadadad00ad0000ad, 0xf4f4f400f40000f4, 0x7777770077000077, 0xc7c7c700c70000c7, 0x8080800080000080, 0x9e9e9e009e00009e
		},
		{
			0x00e0e0e0e0e00000, 0x0005050505050000, 0x0058585858580000, 0x00d9d9d9d9d90000, 0x0067676767670000, 0x004e4e4e4e4e0000, 0x0081818181810000, 0x00cbcbcbcbcb0000,
			0x00c9c9c9c9c90000, 0x000b0b0b0b0b0000, 0x00aeaeaeaeae0000, 0x006a6a6a6a6a0000, 0x00d5d5d5d5d50000, 0x0018181818180000, 0x005d5d5d5d5d0000, 0x0082828282820000,
			0x0046464646460000, 0x00dfdfdfdfdf0000, 0x00d6d6d6d6d60000, 0x0027272727270000, 0x008a8a8a8a8a0000, 0x0032323232320000, 0x004b4b4b4b4b0000, 0x0042424242420000,
			0x00dbdbdbdbdb0000, 0x001c1c1c1c1c0000, 0x009e9e9e9e9e0000, 0x009c9c9c9c9c0000, 0x003a3a3a3a3a0000, 0x00cacacacaca0000, 0x0025252525250000, 0x007b7b7b7b7b0000,
			0x000d0d0d0d0d0000, 0x0071717171710000, 0x005f5f5f5f5f0000, 0x001f1f1f1f1f0000, 0x00f8f8f8f8f80000, 0x00d7d7d7d7d70000, 0x003e3e3e3e3e0000, 0x009d9d9d9d9d0000,
			0x007c7c7c7c7c0000, 0x0060606060600000, 0x00b9b9b9b9b90000, 0x00bebebebebe0000, 0x00bcbcbcbcbc0000, 0x008b8b8b8b8b0000, 0x0016161616160000, 0x0034343434340000,
			0x004d4d4d4d4d0000, 0x00c3c3c3c3c30000, 0x0072727272720000, 0x0095959595950000, 0x00ababababab0000, 0x008e8e8e8e8e0000, 0x00bababababa0000, 0x007a7a7a7a7a0000,
			0x00b3b3b3b3b30000, 0x0002020202020000, 0x00b4b4b4b4b40000, 0x00adadadadad0000, 0x00a2a2a2a2a20000, 0x00acacacacac0000, 0x00d8d8d8d8d80000, 0x009a9a9a9a9a0000,
			0x0017171717170000, 0x001a1a1a1a1a0000, 0x0035353535350000, 0x00cccccccccc0000, 0x00f7f7f7f7f70000, 0x0099999999990000, 0x0061616161610000, 0x005a5a5a5a5a0000,
			0x00e8e8e8e8e80000, 0x0024242424240000, 0x0056565656560000, 0x0040404040400000, 0x00e1e1e1e1e10000, 0x0063636363630000, 0x0009090909090000, 0x0033333333330000,
			0x00bfbfbfbfbf0000, 0x0098989898980000, 0x0097979797970000, 0x0085858585850000, 0x0068686868680000, 0x00fcfcfcfcfc0000, 0x00ececececec0000, 0x000a0a0a0a0a0000,
			0x00dadadadada0000, 0x006f6f6f6f6f0000, 0x0053535353530000, 0x0062626262620000, 0x00a3a3a3a3a30000, 0x002e2e2e2e2e0000, 0x0008080808080000, 0x00afafafafaf0000,
			0x0028282828280000, 0x00b0b0b0b0b00000, 0x0074747474740000, 0x00c2c2c2c2c20000, 0x00bdbdbdbdbd0000, 0x0036363636360000, 0x0022222222220000, 0x0038383838380000,
			0x0064646464640000, 0x001e1e1e1e1e0000, 0x0039393939390000, 0x002c2c2c2c2c0000, 0x00a6a6a6a6a60000, 0x0030303030300000, 0x00e5e5e5e5e50000, 0x0044444444440000,
			0x00fdfdfdfdfd0000, 0x0088888888880000, 0x009f9f9f9f9f0000, 0x0065656565650000, 0x0087878787870000, 0x006b6b6b6b6b0000, 0x00f4f4f4f4f40000, 0x0023232323230000,
			0x0048484848480000, 0x0010101010100000, 0x00d1d1d1d1d10000, 0x0051515151510000, 0x00c0c0c0c0c00000, 0x00f9f9f9f9f90000, 0x00d2d2d2d2d20000, 0x00a0a0a0a0a00000,
			0x0055555555550000, 0x00a1a1a1a1a10000, 0x0041414141410000, 0x00fafafafafa0000, 0x0043434343430000, 0x0013131313130000, 0x00c4c4c4c4c40000, 0x002f2f2f2f2f0000,
			0x00a8a8a8a8a80000, 0x00b6b6b6b6b60000, 0x003c3c3c3c3c0000, 0x002b2b2b2b2b0000, 0x00c1c1c1c1c10000, 0x00ffffffffff0000, 0x00c8c8c8c8c80000, 0x00a5a5a5a5a50000,
			0x0020202020200000, 0x0089898989890000, 0x0000000000000000, 0x0090909090900000, 0x0047474747470000, 0x00efefefefef0000, 0x00eaeaeaeaea0000, 0x00b7b7b7b7b70000,
			0x0015151515150000, 0x0006060606060000, 0x00cdcdcdcdcd0000, 0x00b5b5b5b5b50000, 0x0012121212120000, 0x007e7e7e7e7e0000, 0x00bbbbbbbbbb0000, 0x0029292929290000,
			0x000f0f0f0f0f0000, 0x00b8b8b8b8b80000, 0x0007070707070000, 0x0004040404040000, 0x009b9b9b9b9b0000, 0x0094949494940000, 0x0021212121210000, 0x0066666666660000,
			0x00e6e6e6e6e60000, 0x00cecececece0000, 0x00ededededed0000, 0x00e7e7e7e7e70000, 0x003b3b3b3b3b0000, 0x00fefefefefe0000, 0x007f7f7f7f7f0000, 0x00c5c5c5c5c50000,
			0x00a4a4a4a4a40000, 0x0037373737370000, 0x00b1b1b1b1b10000, 0x004c4c4c4c4c0000, 0x0091919191910000, 0x006e6e6e6e6e0000, 0x008d8d8d8d8d0000, 0x0076767676760000,
			0x0003030303030000, 0x002d2d2d2d2d0000, 0x00dedededede0000, 0x0096969696960000, 0x0026262626260000, 0x007d7d7d7d7d0000, 0x00c6c6c6c6c60000, 0x005c5c5c5c5c0000,
			0x00d3d3d3d3d30000, 0x00f2f2f2f2f20000, 0x004f4f4f4f4f0000, 0x0019191919190000, 0x003f3f3f3f3f0000, 0x00dcdcdcdcdc0000, 0x0079797979790000, 0x001d1d1d1d1d0000,
			0x0052525252520000, 0x00ebebebebeb0000, 0x00f3f3f3f3f30000, 0x006d6d6d6d6d0000, 0x005e5e5e5e5e0000, 0x00fbfbfbfbfb0000, 0x0069696969690000, 0x00b2b2b2b2b20000,
			0x00f0f0f0f0f00000, 0x0031313131310000, 0x000c0c0c0c0c0000, 0x00d4d4d4d4d40000, 0x00cfcfcfcfcf0000, 0x008c8c8c8c8c0000, 0x00e2e2e2e2e20000, 0x0075757575750000,
			0x00a9a9a9a9a90000, 0x004a4a4a4a4a0000, 0x0057575757570000, 0x0084848484840000, 0x0011111111110000, 0x0045454545450000, 0x001b1b1b1b1b0000, 0x00f5f5f5f5f50000,
			0x00e4e4e4e4e40000, 0x000e0e0e0e0e0000, 0x0073737373730000, 0x00aaaaaaaaaa0000, 0x00f1f1f1f1f10000, 0x00dddddddddd0000, 0x0059595959590000, 0x0014141414140000,
			0x006c6c6c6c6c0000, 0x0092929292920000, 0x0054545454540000, 0x00d0d0d0d0d00000, 0x0078787878780000, 0x0070707070700000, 0x00e3e3e3e3e30000, 0x0049494949490000,
			0x0080808080800000, 0x0050505050500000, 0x00a7a7a7a7a70000, 0x00f6f6f6f6f60000, 0x0077777777770000, 0x0093939393930000, 0x0086868686860000, 0x0083838383830000,
			0x002a2a2a2a2a0000, 0x00c7c7c7c7c70000, 0x005b5b5b5b5b0000, 0x00e9e9e9e9e90000, 0x00eeeeeeeeee0000, 0x008f8f8f8f8f0000, 0x0001010101010000, 0x003d3d3d3d3d0000
		},
		{
			0x3800383800383800, 0x4100414100414100, 0x1600161600161600, 0x7600767600767600, 0xd900d9d900d9d900, 0x9300939300939300, 0x6000606000606000, 0xf200f2f200f2f200,
			0x7200727200727200, 0xc200c2c200c2c200, 0xab00abab00abab00, 0x9a009a9a009a9a00, 0x7500757500757500, 0x0600060600060600, 0x5700575700575700, 0xa000a0a000a0a000,
			0x9100919100919100, 0xf700f7f700f7f700, 0xb500b5b500b5b500, 0xc900c9c900c9c900, 0xa200a2a200a2a200, 0x8c008c8c008c8c00, 0xd200d2d200d2d200, 0x9000909000909000,
			0xf600f6f600f6f600, 0x0700070700070700, 0xa700a7a700a7a700, 0x2700272700272700, 0x8e008e8e008e8e00, 0xb200b2b200b2b200, 0x4900494900494900, 0xde00dede00dede00,
			0x4300434300434300, 0x5c005c5c005c5c00, 0xd700d7d700d7d700, 0xc700c7c700c7c700, 0x3e003e3e003e3e00, 0xf500f5f500f5f500, 0x8f008f8f008f8f00, 0x6700676700676700,
			0x1f001f1f001f1f00, 0x1800181800181800, 0x6e006e6e006e6e00, 0xaf00afaf00afaf00, 0x2f002f2f002f2f00, 0xe200e2e200e2e200, 0x8500858500858500, 0x0d000d0d000d0d00,
			0x5300535300535300, 0xf000f0f000f0f000, 0x9c009c9c009c9c00, 0x6500656500656500, 0xea00eaea00eaea00, 0xa300a3a300a3a300, 0xae00aeae00aeae00, 0x9e009e9e009e9e00,
			0xec00ecec00ecec00, 0x8000808000808000, 0x2d002d2d002d2d00, 0x6b006b6b006b6b00, 0xa800a8a800a8a800, 0x2b002b2b002b2b00, 0x3600363600363600, 0xa600a6a600a6a600,
			0xc500c5c500c5c500, 0x8600868600868600, 0x4d004d4d004d4d00, 0x3300333300333300, 0xfd00fdfd00fdfd00, 0x6600666600666600, 0x5800585800585800, 0x9600969600969600,
			0x3a003a3a003a3a00, 0x0900090900090900, 0x9500959500959500, 0x1000101000101000, 0x7800787800787800, 0xd800d8d800d8d800, 0x4200424200424200, 0xcc00cccc00cccc00,
			0xef00efef00efef00, 0x2600262600262600, 0xe500e5e500e5e500, 0x6100616100616100, 0x1a001a1a001a1a00, 0x3f003f3f003f3f00, 0x3b003b3b003b3b00, 0x8200828200828200,
			0xb600b6b600b6b600, 0xdb00dbdb00dbdb00, 0xd400d4d400d4d400, 0x9800989800989800, 0xe800e8e800e8e800, 0x8b008b8b008b8b00, 0x0200020200020200, 0xeb00ebeb00ebeb00,
			0x0a000a0a000a0a00, 0x2c002c2c002c2c00, 0x1d001d1d001d1d00, 0xb000b0b000b0b000, 0x6f006f6f006f6f00, 0x8d008d8d008d8d00, 0x8800888800888800, 0x0e000e0e000e0e00,
			0x1900191900191900, 0x8700878700878700, 0x4e004e4e004e4e00, 0x0b000b0b000b0b00, 0xa900a9a900a9a900, 0x0c000c0c000c0c00, 0x7900797900797900, 0x1100111100111100,
			0x7f007f7f007f7f00, 0x2200222200222200, 0xe700e7e700e7e700, 0x5900595900595900, 0xe100e1e100e1e100, 0xda00dada00dada00, 0x3d003d3d003d3d00, 0xc800c8c800c8c800,
			0x1200121200121200, 0x0400040400040400, 0x7400747400747400, 0x5400545400545400, 0x3000303000303000, 0x7e007e7e007e7e00, 0xb400b4b400b4b400, 0x2800282800282800,
			0x5500555500555500, 0x6800686800686800, 0x5000505000505000, 0xbe00bebe00bebe00, 0xd000d0d000d0d000, 0xc400c4c400c4c400, 0x3100313100313100, 0xcb00cbcb00cbcb00,
			0x2a002a2a002a2a00, 0xad00adad00adad00, 0x0f000f0f000f0f00, 0xca00caca00caca00, 0x7000707000707000, 0xff00ffff00ffff00, 0x3200323200323200, 0x6900696900696900,
			0x0800080800080800, 0x6200626200626200, 0x0000000000000000, 0x2400242400242400, 0xd100d1d100d1d100, 0xfb00fbfb00fbfb00, 0xba00baba00baba00, 0xed00eded00eded00,
			0x4500454500454500, 0x8100818100818100, 0x7300737300737300, 0x6d006d6d006d6d00, 0x8400848400848400, 0x9f009f9f009f9f00, 0xee00eeee00eeee00, 0x4a004a4a004a4a00,
			0xc300c3c300c3c300, 0x2e002e2e002e2e00, 0xc100c1c100c1c100, 0x0100010100010100, 0xe600e6e600e6e600, 0x2500252500252500, 0x4800484800484800, 0x9900999900999900,
			0xb900b9b900b9b900, 0xb300b3b300b3b300, 0x7b007b7b007b7b00, 0xf900f9f900f9f900, 0xce00cece00cece00, 0xbf00bfbf00bfbf00, 0xdf00dfdf00dfdf00, 0x7100717100717100,
			0x2900292900292900, 0xcd00cdcd00cdcd00, 0x6c006c6c006c6c00, 0x1300131300131300, 0x6400646400646400, 0x9b009b9b009b9b00, 0x6300636300636300, 0x9d009d9d009d9d00,
			0xc000c0c000c0c000, 0x4b004b4b004b4b00, 0xb700b7b700b7b700, 0xa500a5a500a5a500, 0x8900898900898900, 0x5f005f5f005f5f00, 0xb100b1b100b1b100, 0x1700171700171700,
			0xf400f4f400f4f400, 0xbc00bcbc00bcbc00, 0xd300d3d300d3d300, 0x4600464600464600, 0xcf00cfcf00cfcf00, 0x3700373700373700, 0x5e005e5e005e5e00, 0x4700474700474700,
			0x9400949400949400, 0xfa00fafa00fafa00, 0xfc00fcfc00fcfc00, 0x5b005b5b005b5b00, 0x9700979700979700, 0xfe00fefe00fefe00, 0x5a005a5a005a5a00, 0xac00acac00acac00,
			0x3c003c3c003c3c00, 0x4c004c4c004c4c00, 0x0300030300030300, 0x3500353500353500, 0xf300f3f300f3f300, 0x2300232300232300, 0xb800b8b800b8b800, 0x5d005d5d005d5d00,
			0x6a006a6a006a6a00, 0x9200929200929200, 0xd500d5d500d5d500, 0x2100212100212100, 0x4400444400444400, 0x5100515100515100, 0xc600c6c600c6c600, 0x7d007d7d007d7d00,
			0x3900393900393900, 0x8300838300838300, 0xdc00dcdc00dcdc00, 0xaa00aaaa00aaaa00, 0x7c007c7c007c7c00, 0x7700777700777700, 0x5600565600565600, 0x0500050500050500,
			0x1b001b1b001b1b00, 0xa400a4a400a4a400, 0x1500151500151500, 0x3400343400343400, 0x1e001e1e001e1e00, 0x1c001c1c001c1c00, 0xf800f8f800f8f800, 0x5200525200525200,
			0x2000202000202000, 0x1400141400141400, 0xe900e9e900e9e900, 0xbd00bdbd00bdbd00, 0xdd00dddd00dddd00, 0xe400e4e400e4e400, 0xa100a1a100a1a100, 0xe000e0e000e0e000,
			0x8a008a8a008a8a00, 0xf100f1f100f1f100, 0xd600d6d600d6d600, 0x7a007a7a007a7a00, 0xbb00bbbb00bbbb00, 0xe300e3e300e3e300, 0x4000404000404000, 0x4f004f4f004f4f00
		},
		{
			0x7070007000007070, 0x2c2c002c00002c2c, 0xb3b300b30000b3b3, 0xc0c000c00000c0c0, 0xe4e400e40000e4e4, 0x5757005700005757, 0xeaea00ea0000eaea, 0xaeae00ae0000aeae,
			0x2323002300002323, 0x6b6b006b00006b6b, 0x4545004500004545, 0xa5a500a50000a5a5, 0xeded00ed0000eded, 0x4f4f004f00004f4f, 0x1d1d001d00001d1d, 0x9292009200009292,
			0x8686008600008686, 0xafaf00af0000afaf, 0x7c7c007c00007c7c, 0x1f1f001f00001f1f, 0x3e3e003e00003e3e, 0xdcdc00dc0000dcdc, 0x5e5e005e00005e5e, 0x0b0b000b00000b0b,
			0xa6a600a60000a6a6, 0x3939003900003939, 0xd5d500d50000d5d5, 0x5d5d005d00005d5d, 0xd9d900d90000d9d9, 0x5a5a005a00005a5a, 0x5151005100005151, 0x6c6c006c00006c6c,
			0x8b8b008b00008b8b, 0x9a9a009a00009a9a, 0xfbfb00fb0000fbfb, 0xb0b000b00000b0b0, 0x7474007400007474, 0x2b2b002b00002b2b, 0xf0f000f00000f0f0, 0x8484008400008484,
			0xdfdf00df0000dfdf, 0xcbcb00cb0000cbcb, 0x3434003400003434, 0x7676007600007676, 0x6d6d006d00006d6d, 0xa9a900a90000a9a9, 0xd1d100d10000d1d1, 0x0404000400000404,
			0x1414001400001414, 0x3a3a003a00003a3a, 0xdede00de0000dede, 0x1111001100001111, 0x3232003200003232, 0x9c9c009c00009c9c, 0x5353005300005353, 0xf2f200f20000f2f2,
			0xfefe00fe0000fefe, 0xcfcf00cf0000cfcf, 0xc3c300c30000c3c3, 0x7a7a007a00007a7a, 0x2424002400002424, 0xe8e800e80000e8e8, 0x6060006000006060, 0x6969006900006969,
			0xaaaa00aa0000aaaa, 0xa0a000a00000a0a0, 0xa1a100a10000a1a1, 0x6262006200006262, 0x5454005400005454, 0x1e1e001e00001e1e, 0xe0e000e00000e0e0, 0x6464006400006464,
			0x1010001000001010, 0x0000000000000000, 0xa3a300a30000a3a3, 0x7575007500007575, 0x8a8a008a00008a8a, 0xe6e600e60000e6e6, 0x0909000900000909, 0xdddd00dd0000dddd,
			0x8787008700008787, 0x8383008300008383, 0xcdcd00cd0000cdcd, 0x9090009000009090, 0x7373007300007373, 0xf6f600f60000f6f6, 0x9d9d009d00009d9d, 0xbfbf00bf0000bfbf,
			0x5252005200005252, 0xd8d800d80000d8d8, 0xc8c800c80000c8c8, 0xc6c600c60000c6c6, 0x8181008100008181, 0x6f6f006f00006f6f, 0x1313001300001313, 0x6363006300006363,
			0xe9e900e90000e9e9, 0xa7a700a70000a7a7, 0x9f9f009f00009f9f, 0xbcbc00bc0000bcbc, 0x2929002900002929, 0xf9f900f90000f9f9, 0x2f2f002f00002f2f, 0xb4b400b40000b4b4,
			0x7878007800007878, 0x0606000600000606, 0xe7e700e70000e7e7, 0x7171007100007171, 0xd4d400d40000d4d4, 0xabab00ab0000abab, 0x8888008800008888, 0x8d8d008d00008d8d,
			0x7272007200007272, 0xb9b900b90000b9b9, 0xf8f800f80000f8f8, 0xacac00ac0000acac, 0x3636003600003636, 0x2a2a002a00002a2a, 0x3c3c003c00003c3c, 0xf1f100f10000f1f1,
			0x4040004000004040, 0xd3d300d30000d3d3, 0xbbbb00bb0000bbbb, 0x4343004300004343, 0x1515001500001515, 0xadad00ad0000adad, 0x7777007700007777, 0x8080008000008080,
			0x8282008200008282, 0xecec00ec0000ecec, 0x2727002700002727, 0xe5e500e50000e5e5, 0x8585008500008585, 0x3535003500003535, 0x0c0c000c00000c0c, 0x4141004100004141,
			0xefef00ef0000efef, 0x9393009300009393, 0x1919001900001919, 0x2121002100002121, 0x0e0e000e00000e0e, 0x4e4e004e00004e4e, 0x6565006500006565, 0xbdbd00bd0000bdbd,
			0xb8b800b80000b8b8, 0x8f8f008f00008f8f, 0xebeb00eb0000ebeb, 0xcece00ce0000cece, 0x3030003000003030, 0x5f5f005f00005f5f, 0xc5c500c50000c5c5, 0x1a1a001a00001a1a,
			0xe1e100e10000e1e1, 0xcaca00ca0000caca, 0x4747004700004747, 0x3d3d003d00003d3d, 0x0101000100000101, 0xd6d600d60000d6d6, 0x5656005600005656, 0x4d4d004d00004d4d,
			0x0d0d000d00000d0d, 0x6666006600006666, 0xcccc00cc0000cccc, 0x2d2d002d00002d2d, 0x1212001200001212, 0x2020002000002020, 0xb1b100b10000b1b1, 0x9999009900009999,
			0x4c4c004c00004c4c, 0xc2c200c20000c2c2, 0x7e7e007e00007e7e, 0x0505000500000505, 0xb7b700b70000b7b7, 0x3131003100003131, 0x1717001700001717, 0xd7d700d70000d7d7,
			0x5858005800005858, 0x6161006100006161, 0x1b1b001b00001b1b, 0x1c1c001c00001c1c, 0x0f0f000f00000f0f, 0x1616001600001616, 0x1818001800001818, 0x2222002200002222,
			0x4444004400004444, 0xb2b200b20000b2b2, 0xb5b500b50000b5b5, 0x9191009100009191, 0x0808000800000808, 0xa8a800a80000a8a8, 0xfcfc00fc0000fcfc, 0x5050005000005050,
			0xd0d000d00000d0d0, 0x7d7d007d00007d7d, 0x8989008900008989, 0x9797009700009797, 0x5b5b005b00005b5b, 0x9595009500009595, 0xffff00ff0000ffff, 0xd2d200d20000d2d2,
			0xc4c400c40000c4c4, 0x4848004800004848, 0xf7f700f70000f7f7, 0xdbdb00db0000dbdb, 0x0303000300000303, 0xdada00da0000dada, 0x3f3f003f00003f3f, 0x9494009400009494,
			0x5c5c005c00005c5c, 0x0202000200000202, 0x4a4a004a00004a4a, 0x3333003300003333, 0x6767006700006767, 0xf3f300f30000f3f3, 0x7f7f007f00007f7f, 0xe2e200e20000e2e2,
			0x9b9b009b00009b9b, 0x2626002600002626, 0x3737003700003737, 0x3b3b003b00003b3b, 0x9696009600009696, 0x4b4b004b00004b4b, 0xbebe00be0000bebe, 0x2e2e002e00002e2e,
			0x7979007900007979, 0x8c8c008c00008c8c, 0x6e6e006e00006e6e, 0x8e8e008e00008e8e, 0xf5f500f50000f5f5, 0xb6b600b60000b6b6, 0xfdfd00fd0000fdfd, 0x5959005900005959,
			0x9898009800009898, 0x6a6a006a00006a6a, 0x4646004600004646, 0xbaba00ba0000baba, 0x2525002500002525, 0x4242004200004242, 0xa2a200a20000a2a2, 0xfafa00fa0000fafa,
			0x0707000700000707, 0x5555005500005555, 0xeeee00ee0000eeee, 0x0a0a000a00000a0a, 0x4949004900004949, 0x6868006800006868, 0x3838003800003838, 0xa4a400a40000a4a4,
			0x2828002800002828, 0x7b7b007b00007b7b, 0xc9c900c90000c9c9, 0xc1c100c10000c1c1, 0xe3e300e30000e3e3, 0xf4f400f40000f4f4, 0xc7c700c70000c7c7, 0x9e9e009e00009e9e
		},
		{
			0x00e0e0e000e0e0e0, 0x0005050500050505, 0x0058585800585858, 0x00d9d9d900d9d9d9, 0x0067676700676767, 0x004e4e4e004e4e4e, 0x0081818100818181, 0x00cbcbcb00cbcbcb,
			0x00c9c9c900c9c9c9, 0x000b0b0b000b0b0b, 0x00aeaeae00aeaeae, 0x006a6a6a006a6a6a, 0x00d5d5d500d5d5d5, 0x0018181800181818, 0x005d5d5d005d5d5d, 0x0082828200828282,
			0x0046464600464646, 0x00dfdfdf00dfdfdf, 0x00d6d6d600d6d6d6, 0x0027272700272727, 0x008a8a8a008a8a8a, 0x0032323200323232, 0x004b4b4b004b4b4b, 0x0042424200424242,
			0x00dbdbdb00dbdbdb, 0x001c1c1c001c1c1c, 0x009e9e9e009e9e9e, 0x009c9c9c009c9c9c, 0x003a3a3a003a3a3a, 0x00cacaca00cacaca, 0x0025252500252525, 0x007b7b7b007b7b7b,
			0x000d0d0d000d0d0d, 0x0071717100717171, 0x005f5f5f005f5f5f, 0x001f1f1f001f1f1f, 0x00f8f8f800f8f8f8, 0x00d7d7d700d7d7d7, 0x003e3e3e003e3e3e, 0x009d9d9d009d9d9d,
			0x007c7c7c007c7c7c, 0x0060606000606060, 0x00b9b9b900b9b9b9, 0x00bebebe00bebebe, 0x00bcbcbc00bcbcbc, 0x008b8b8b008b8b8b, 0x0016161600161616, 0x0034343400343434,
			0x004d4d4d004d4d4d, 0x00c3c3c300c3c3c3, 0x0072727200727272, 0x0095959500959595, 0x00ababab00ababab, 0x008e8e8e008e8e8e, 0x00bababa00bababa, 0x007a7a7a007a7a7a,
			0x00b3b3b300b3b3b3, 0x0002020200020202, 0x00b4b4b400b4b4b4, 0x00adadad00adadad, 0x00a2a2a200a2a2a2, 0x00acacac00acacac, 0x00d8d8d800d8d8d8, 0x009a9a9a009a9a9a,
			0x0017171700171717, 0x001a1a1a001a1a1a, 0x0035353500353535, 0x00cccccc00cccccc, 0x00f7f7f700f7f7f7, 0x0099999900999999, 0x0061616100616161, 0x005a5a5a005a5a5a,
			0x00e8e8e800e8e8e8, 0x0024242400242424, 0x0056565600565656, 0x0040404000404040, 0x00e1e1e100e1e1e1, 0x0063636300636363, 0x0009090900090909, 0x0033333300333333,
			0x00bfbfbf00bfbfbf, 0x0098989800989898, 0x0097979700979797, 0x0085858500858585, 0x0068686800686868, 0x00fcfcfc00fcfcfc, 0x00ececec00ececec, 0x000a0a0a000a0a0a,
			0x00dadada00dadada, 0x006f6f6f006f6f6f, 0x0053535300535353, 0x0062626200626262, 0x00a3a3a300a3a3a3, 0x002e2e2e002e2e2e, 0x0008080800080808, 0x00afafaf00afafaf,
			0x0028282800282828, 0x00b0b0b000b0b0b0, 0x0074747400747474, 0x00c2c2c200c2c2c2, 0x00bdbdbd00bdbdbd, 0x0036363600363636, 0x0022222200222222, 0x0038383800383838,
			0x0064646400646464, 0x001e1e1e001e1e1e, 0x0039393900393939, 0x002c2c2c002c2c2c, 0x00a6a6a600a6a6a6, 0x0030303000303030, 0x00e5e5e500e5e5e5, 0x0044444400444444,
			0x00fdfdfd00fdfdfd, 0x0088888800888888, 0x009f9f9f009f9f9f, 0x0065656500656565, 0x0087878700878787, 0x006b6b6b006b6b6b, 0x00f4f4f400f4f4f4, 0x0023232300232323,
			0x0048484800484848, 0x0010101000101010, 0x00d1d1d100d1d1d1, 0x0051515100515151, 0x00c0c0c000c0c0c0, 0x00f9f9f900f9f9f9, 0x00d2d2d200d2d2d2, 0x00a0a0a000a0a0a0,
			0x0055555500555555, 0x00a1a1a100a1a1a1, 0x0041414100414141, 0x00fafafa00fafafa, 0x0043434300434343, 0x0013131300131313, 0x00c4c4c400c4c4c4, 0x002f2f2f002f2f2f,
			0x00a8a8a800a8a8a8, 0x00b6b6b600b6b6b6, 0x003c3c3c003c3c3c, 0x002b2b2b002b2b2b, 0x00c1c1c100c1c1c1, 0x00ffffff00ffffff, 0x00c8c8c800c8c8c8, 0x00a5a5a500a5a5a5,
			0x0020202000202020, 0x0089898900898989, 0x0000000000000000, 0x0090909000909090, 0x0047474700474747, 0x00efefef00efefef, 0x00eaeaea00eaeaea, 0x00b7b7b700b7b7b7,
			0x0015151500151515, 0x0006060600060606, 0x00cdcdcd00cdcdcd, 0x00b5b5b500b5b5b5, 0x0012121200121212, 0x007e7e7e007e7e7e, 0x00bbbbbb00bbbbbb, 0x0029292900292929,
			0x000f0f0f000f0f0f, 0x00b8b8b800b8b8b8, 0x0007070700070707, 0x0004040400040404, 0x009b9b9b009b9b9b, 0x0094949400949494, 0x0021212100212121, 0x0066666600666666,
			0x00e6e6e600e6e6e6, 0x00cecece00cecece, 0x00ededed00ededed, 0x00e7e7e700e7e7e7, 0x003b3b3b003b3b3b, 0x00fefefe00fefefe, 0x007f7f7f007f7f7f, 0x00c5c5c500c5c5c5,
			0x00a4a4a400a4a4a4, 0x0037373700373737, 0x00b1b1b100b1b1b1, 0x004c4c4c004c4c4c, 0x0091919100919191, 0x006e6e6e006e6e6e, 0x008d8d8d008d8d8d, 0x0076767600767676,
			0x0003030300030303, 0x002d2d2d002d2d2d, 0x00dedede00dedede, 0x0096969600969696, 0x0026262600262626, 0x007d7d7d007d7d7d, 0x00c6c6c600c6c6c6, 0x005c5c5c005c5c5c,
			0x00d3d3d300d3d3d3, 0x00f2f2f200f2f2f2, 0x004f4f4f004f4f4f, 0x0019191900191919, 0x003f3f3f003f3f3f, 0x00dcdcdc00dcdcdc, 0x0079797900797979, 0x001d1d1d001d1d1d,
			0x0052525200525252, 0x00ebebeb00ebebeb, 0x00f3f3f300f3f3f3, 0x006d6d6d006d6d6d, 0x005e5e5e005e5e5e, 0x00fbfbfb00fbfbfb, 0x0069696900696969, 0x00b2b2b200b2b2b2,
			0x00f0f0f000f0f0f0, 0x0031313100313131, 0x000c0c0c000c0c0c, 0x00d4d4d400d4d4d4, 0x00cfcfcf00cfcfcf, 0x008c8c8c008c8c8c, 0x00e2e2e200e2e2e2, 0x0075757500757575,
			0x00a9a9a900a9a9a9, 0x004a4a4a004a4a4a, 0x0057575700575757, 0x0084848400848484, 0x0011111100111111, 0x0045454500454545, 0x001b1b1b001b1b1b, 0x00f5f5f500f5f5f5,
			0x00e4e4e400e4e4e4, 0x000e0e0e000e0e0e, 0x0073737300737373, 0x00aaaaaa00aaaaaa, 0x00f1f1f100f1f1f1, 0x00dddddd00dddddd, 0x0059595900595959, 0x0014141400141414,
			0x006c6c6c006c6c6c, 0x0092929200929292, 0x0054545400545454, 0x00d0d0d000d0d0d0, 0x0078787800787878, 0x0070707000707070, 0x00e3e3e300e3e3e3, 0x0049494900494949,
			0x0080808000808080, 0x0050505000505050, 0x00a7a7a700a7a7a7, 0x00f6f6f600f6f6f6, 0x0077777700777777, 0x0093939300939393, 0x0086868600868686, 0x0083838300838383,
			0x002a2a2a002a2a2a, 0x00c7c7c700c7c7c7, 0x005b5b5b005b5b5b, 0x00e9e9e900e9e9e9, 0x00eeeeee00eeeeee, 0x008f8f8f008f8f8f, 0x0001010100010101, 0x003d3d3d003d3d3d
		},
		{
			0x3800383838003838, 0x4100414141004141, 0x1600161616001616, 0x7600767676007676, 0xd900d9d9d900d9d9, 0x9300939393009393, 0x6000606060006060, 0xf200f2f2f200f2f2,
			0x7200727272007272, 0xc200c2c2c200c2c2, 0xab00ababab00abab, 0x9a009a9a9a009a9a, 0x7500757575007575, 0x0600060606000606, 0x5700575757005757, 0xa000a0a0a000a0a0,
			0x9100919191009191, 0xf700f7f7f700f7f7, 0xb500b5b5b500b5b5, 0xc900c9c9c900c9c9, 0xa200a2a2a200a2a2, 0x8c008c8c8c008c8c, 0xd200d2d2d200d2d2, 0x9000909090009090,
			0xf600f6f6f600f6f6, 0x0700070707000707, 0xa700a7a7a700a7a7, 0x2700272727002727, 0x8e008e8e8e008e8e, 0xb200b2b2b200b2b2, 0x4900494949004949, 0xde00dedede00dede,
			0x4300434343004343, 0x5c005c5c5c005c5c, 0xd700d7d7d700d7d7, 0xc700c7c7c700c7c7, 0x3e003e3e3e003e3e, 0xf500f5f5f500f5f5, 0x8f008f8f8f008f8f, 0x6700676767006767,
			0x1f001f1f1f001f1f, 0x1800181818001818, 0x6e006e6e6e006e6e, 0xaf00afafaf00afaf, 0x2f002f2f2f002f2f, 0xe200e2e2e200e2e2, 0x8500858585008585, 0x0d000d0d0d000d0d,
			0x5300535353005353, 0xf000f0f0f000f0f0, 0x9c009c9c9c009c9c, 0x6500656565006565, 0xea00eaeaea00eaea, 0xa300a3a3a300a3a3, 0xae00aeaeae00aeae, 0x9e009e9e9e009e9e,
			0xec00ececec00ecec, 0x8000808080008080, 0x2d002d2d2d002d2d, 0x6b006b6b6b006b6b, 0xa800a8a8a800a8a8, 0x2b002b2b2b002b2b, 0x3600363636003636, 0xa600a6a6a600a6a6,
			0xc500c5c5c500c5c5, 0x8600868686008686, 0x4d004d4d4d004d4d, 0x3300333333003333, 0xfd00fdfdfd00fdfd, 0x6600666666006666, 0x5800585858005858, 0x9600969696009696,
			0x3a003a3a3a003a3a, 0x0900090909000909, 0x9500959595009595, 0x1000101010001010, 0x7800787878007878, 0xd800d8d8d800d8d8, 0x4200424242004242, 0xcc00cccccc00cccc,
			0xef00efefef00efef, 0x2600262626002626, 0xe500e5e5e500e5e5, 0x6100616161006161, 0x1a001a1a1a001a1a, 0x3f003f3f3f003f3f, 0x3b003b3b3b003b3b, 0x8200828282008282,
			0xb600b6b6b600b6b6, 0xdb00dbdbdb00dbdb, 0xd400d4d4d400d4d4, 0x9800989898009898, 0xe800e8e8e800e8e8, 0x8b008b8b8b008b8b, 0x0200020202000202, 0xeb00ebebeb00ebeb,
			0x0a000a0a0a000a0a, 0x2c002c2c2c002c2c, 0x1d001d1d1d001d1d, 0xb000b0b0b000b0b0, 0x6f006f6f6f006f6f, 0x8d008d8d8d008d8d, 0x8800888888008888, 0x0e000e0e0e000e0e,
			0x1900191919001919, 0x8700878787008787, 0x4e004e4e4e004e4e, 0x0b000b0b0b000b0b, 0xa900a9a9a900a9a9, 0x0c000c0c0c000c0c, 0x7900797979007979, 0x1100111111001111,
			0x7f007f7f7f007f7f, 0x2200222222002222, 0xe700e7e7e700e7e7, 0x5900595959005959, 0xe100e1e1e100e1e1, 0xda00dadada00dada, 0x3d003d3d3d003d3d, 0xc800c8c8c800c8c8,
			0x1200121212001212, 0x0400040404000404, 0x7400747474007474, 0x5400545454005454, 0x3000303030003030, 0x7e007e7e7e007e7e, 0xb400b4b4b400b4b4, 0x2800282828002828,
			0x5500555555005555, 0x6800686868006868, 0x5000505050005050, 0xbe00bebebe00bebe, 0xd000d0d0d000d0d0, 0xc400c4c4c400c4c4, 0x3100313131003131, 0xcb00cbcbcb00cbcb,
			0x2a002a2a2a002a2a, 0xad00adadad00adad, 0x0f000f0f0f000f0f, 0xca00cacaca00caca, 0x7000707070007070, 0xff00ffffff00ffff, 0x3200323232003232, 0x6900696969006969,
			0x0800080808000808, 0x6200626262006262, 0x0000000000000000, 0x2400242424002424, 0xd100d1d1d100d1d1, 0xfb00fbfbfb00fbfb, 0xba00bababa00baba, 0xed00ededed00eded,
			0x4500454545004545, 0x8100818181008181, 0x7300737373007373, 0x6d006d6d6d006d6d, 0x8400848484008484, 0x9f009f9f9f009f9f, 0xee00eeeeee00eeee, 0x4a004a4a4a004a4a,
			0xc300c3c3c300c3c3, 0x2e002e2e2e002e2e, 0xc100c1c1c100c1c1, 0x0100010101000101, 0xe600e6e6e600e6e6, 0x2500252525002525, 0x4800484848004848, 0x9900999999009999,
			0xb900b9b9b900b9b9, 0xb300b3b3b300b3b3, 0x7b007b7b7b007b7b, 0xf900f9f9f900f9f9, 0xce00cecece00cece, 0xbf00bfbfbf00bfbf, 0xdf00dfdfdf00dfdf, 0x7100717171007171,
			0x2900292929002929, 0xcd00cdcdcd00cdcd, 0x6c006c6c6c006c6c, 0x1300131313001313, 0x6400646464006464, 0x9b009b9b9b009b9b, 0x6300636363006363, 0x9d009d9d9d009d9d,
			0xc000c0c0c000c0c0, 0x4b004b4b4b004b4b, 0xb700b7b7b700b7b7, 0xa500a5a5a500a5a5, 0x8900898989008989, 0x5f005f5f5f005f5f, 0xb100b1b1b100b1b1, 0x1700171717001717,
			0xf400f4f4f400f4f4, 0xbc00bcbcbc00bcbc, 0xd300d3d3d300d3d3, 0x4600464646004646, 0xcf00cfcfcf00cfcf, 0x3700373737003737, 0x5e005e5e5e005e5e, 0x4700474747004747,
			0x9400949494009494, 0xfa00fafafa00fafa, 0xfc00fcfcfc00fcfc, 0x5b005b5b5b005b5b, 0x9700979797009797, 0xfe00fefefe00fefe, 0x5a005a5a5a005a5a, 0xac00acacac00acac,
			0x3c003c3c3c003c3c, 0x4c004c4c4c004c4c, 0x0300030303000303, 0x3500353535003535, 0xf300f3f3f300f3f3, 0x2300232323002323, 0xb800b8b8b800b8b8, 0x5d005d5d5d005d5d,
			0x6a006a6a6a006a6a, 0x9200929292009292, 0xd500d5d5d500d5d5, 0x2100212121002121, 0x4400444444004444, 0x5100515151005151, 0xc600c6c6c600c6c6, 0x7d007d7d7d007d7d,
			0x3900393939003939, 0x8300838383008383, 0xdc00dcdcdc00dcdc, 0xaa00aaaaaa00aaaa, 0x7c007c7c7c007c7c, 0x7700777777007777, 0x5600565656005656, 0x0500050505000505,
			0x1b001b1b1b001b1b, 0xa400a4a4a400a4a4, 0x1500151515001515, 0x3400343434003434, 0x1e001e1e1e001e1e, 0x1c001c1c1c001c1c, 0xf800f8f8f800f8f8, 0x5200525252005252,
			0x2000202020002020, 0x1400141414001414, 0xe900e9e9e900e9e9, 0xbd00bdbdbd00bdbd, 0xdd00dddddd00dddd, 0xe400e4e4e400e4e4, 0xa100a1a1a100a1a1, 0xe000e0e0e000e0e0,
			0x8a008a8a8a008a8a, 0xf100f1f1f100f1f1, 0xd600d6d6d600d6d6, 0x7a007a7a7a007a7a, 0xbb00bbbbbb00bbbb, 0xe300e3e3e300e3e3, 0x4000404040004040, 0x4f004f4f4f004f4f
		},
		{
			0x7070007070700070, 0x2c2c002c2c2c002c, 0xb3b300b3b3b300b3, 0xc0c000c0c0c000c0, 0xe4e400e4e4e400e4, 0x5757005757570057, 0xeaea00eaeaea00ea, 0xaeae00aeaeae00ae,
			0x2323002323230023, 0x6b6b006b6b6b006b, 0x4545004545450045, 0xa5a500a5a5a500a5, 0xeded00ededed00ed, 0x4f4f004f4f4f004f, 0x1d1d001d1d1d001d, 0x9292009292920092,
			0x8686008686860086, 0xafaf00afafaf00af, 0x7c7c007c7c7c007c, 0x1f1f001f1f1f001f, 0x3e3e003e3e3e003e, 0xdcdc00dcdcdc00dc, 0x5e5e005e5e5e005e, 0x0b0b000b0b0b000b,
			0xa6a600a6a6a600a6, 0x3939003939390039, 0xd5d500d5d5d500d5, 0x5d5d005d5d5d005d, 0xd9d900d9d9d900d9, 0x5a5a005a5a5a005a, 0x5151005151510051, 0x6c6c006c6c6c006c,
			0x8b8b008b8b8b008b, 0x9a9a009a9a9a009a, 0xfbfb00fbfbfb00fb, 0xb0b000b0b0b000b0, 0x7474007474740074, 0x2b2b002b2b2b002b, 0xf0f000f0f0f000f0, 0x8484008484840084,
			0xdfdf00dfdfdf00df, 0xcbcb00cbcbcb00cb, 0x3434003434340034, 0x7676007676760076, 0x6d6d006d6d6d006d, 0xa9a900a9a9a900a9, 0xd1d100d1d1d100d1, 0x0404000404040004,
			0x1414001414140014, 0x3a3a003a3a3a003a, 0xdede00dedede00de, 0x1111001111110011, 0x3232003232320032, 0x9c9c009c9c9c009c, 0x5353005353530053, 0xf2f200f2f2f200f2,
			0xfefe00fefefe00fe, 0xcfcf00cfcfcf00cf, 0xc3c300c3c3c300c3, 0x7a7a007a7a7a007a, 0x2424002424240024, 0xe8e800e8e8e800e8, 0x6060006060600060, 0x6969006969690069,
			0xaaaa00aaaaaa00aa, 0xa0a000a0a0a000a0, 0xa1a100a1a1a100a1, 0x6262006262620062, 0x5454005454540054, 0x1e1e001e1e1e001e, 0xe0e000e0e0e000e0, 0x6464006464640064,
			0x1010001010100010, 0x0000000000000000, 0xa3a300a3a3a300a3, 0x7575007575750075, 0x8a8a008a8a8a008a, 0xe6e600e6e6e600e6, 0x0909000909090009, 0xdddd00dddddd00dd,
			0x8787008787870087, 0x8383008383830083, 0xcdcd00cdcdcd00cd, 0x9090009090900090, 0x7373007373730073, 0xf6f600f6f6f600f6, 0x9d9d009d9d9d009d, 0xbfbf00bfbfbf00bf,
			0x5252005252520052, 0xd8d800d8d8d800d8, 0xc8c800c8c8c800c8, 0xc6c600c6c6c600c6, 0x8181008181810081, 0x6f6f006f6f6f006f, 0x1313001313130013, 0x6363006363630063,
			0xe9e900e9e9e900e9, 0xa7a700a7a7a700a7, 0x9f9f009f9f9f009f, 0xbcbc00bcbcbc00bc, 0x2929002929290029, 0xf9f900f9f9f900f9, 0x2f2f002f2f2f002f, 0xb4b400b4b4b400b4,
			0x7878007878780078, 0x0606000606060006, 0xe7e700e7e7e700e7, 0x7171007171710071, 0xd4d400d4d4d400d4, 0xabab00ababab00ab, 0x8888008888880088, 0x8d8d008d8d8d008d,
			0x7272007272720072, 0xb9b900b9b9b900b9, 0xf8f800f8f8f800f8, 0xacac00acacac00ac, 0x3636003636360036, 0x2a2a002a2a2a002a, 0x3c3c003c3c3c003c, 0xf1f100f1f1f100f1,
			0x4040004040400040, 0xd3d300d3d3d300d3, 0xbbbb00bbbbbb00bb, 0x4343004343430043, 0x1515001515150015, 0xadad00adadad00ad, 0x7777007777770077, 0x8080008080800080,
			0x8282008282820082, 0xecec00ececec00ec, 0x2727002727270027, 0xe5e500e5e5e500e5, 0x8585008585850085, 0x3535003535350035, 0x0c0c000c0c0c000c, 0x4141004141410041,
			0xefef00efefef00ef, 0x9393009393930093, 0x1919001919190019, 0x2121002121210021, 0x0e0e000e0e0e000e, 0x4e4e004e4e4e004e, 0x6565006565650065, 0xbdbd00bdbdbd00bd,
			0xb8b800b8b8b800b8, 0x8f8f008f8f8f008f, 0xebeb00ebebeb00eb, 0xcece00cecece00ce, 0x3030003030300030, 0x5f5f005f5f5f005f, 0xc5c500c5c5c500c5, 0x1a1a001a1a1a001a,
			0xe1e100e1e1e100e1, 0xcaca00cacaca00ca, 0x4747004747470047, 0x3d3d003d3d3d003d, 0x0101000101010001, 0xd6d600d6d6d600d6, 0x5656005656560056, 0x4d4d004d4d4d004d,
			0x0d0d000d0d0d000d, 0x6666006666660066, 0xcccc00cccccc00cc, 0x2d2d002d2d2d002d, 0x1212001212120012, 0x2020002020200020, 0xb1b100b1b1b100b1, 0x9999009999990099,
			0x4c4c004c4c4c004c, 0xc2c200c2c2c200c2, 0x7e7e007e7e7e007e, 0x0505000505050005, 0xb7b700b7b7b700b7, 0x3131003131310031, 0x1717001717170017, 0xd7d700d7d7d700d7,
			0x5858005858580058, 0x6161006161610061, 0x1b1b001b1b1b001b, 0x1c1c001c1c1c001c, 0x0f0f000f0f0f000f, 0x1616001616160016, 0x1818001818180018, 0x2222002222220022,
			0x4444004444440044, 0xb2b200b2b2b200b2, 0xb5b500b5b5b500b5, 0x9191009191910091, 0x0808000808080008, 0xa8a800a8a8a800a8, 0xfcfc00fcfcfc00fc, 0x5050005050500050,
			0xd0d000d0d0d000d0, 0x7d7d007d7d7d007d, 0x8989008989890089, 0x9797009797970097, 0x5b5b005b5b5b005b, 0x9595009595950095, 0xffff00ffffff00ff, 0xd2d200d2d2d200d2,
			0xc4c400c4c4c400c4, 0x4848004848480048, 0xf7f700f7f7f700f7, 0xdbdb00dbdbdb00db, 0x0303000303030003, 0xdada00dadada00da, 0x3f3f003f3f3f003f, 0x9494009494940094,
			0x5c5c005c5c5c005c, 0x0202000202020002, 0x4a4a004a4a4a004a, 0x3333003333330033, 0x6767006767670067, 0xf3f300f3f3f300f3, 0x7f7f007f7f7f007f, 0xe2e200e2e2e200e2,
			0x9b9b009b9b9b009b, 0x2626002626260026, 0x3737003737370037, 0x3b3b003b3b3b003b, 0x9696009696960096, 0x4b4b004b4b4b004b, 0xbebe00bebebe00be, 0x2e2e002e2e2e002e,
			0x7979007979790079, 0x8c8c008c8c8c008c, 0x6e6e006e6e6e006e, 0x8e8e008e8e8e008e, 0xf5f500f5f5f500f5, 0xb6b600b6b6b600b6, 0xfdfd00fdfdfd00fd, 0x5959005959590059,
			0x9898009898980098, 0x6a6a006a6a6a006a, 0x4646004646460046, 0xbaba00bababa00ba, 0x2525002525250025, 0x4242004242420042, 0xa2a200a2a2a200a2, 0xfafa00fafafa00fa,
			0x0707000707070007, 0x5555005555550055, 0xeeee00eeeeee00ee, 0x0a0a000a0a0a000a, 0x4949004949490049, 0x6868006868680068, 0x3838003838380038, 0xa4a400a4a4a400a4,
			0x2828002828280028, 0x7b7b007b7b7b007b, 0xc9c900c9c9c900c9, 0xc1c100c1c1c100c1, 0xe3e300e3e3e300e3, 0xf4f400f4f4f400f4, 0xc7c700c7c7c700c7, 0x9e9e009e9e9e009e
		},
		{
			0x7070700070707000, 0x8282820082828200, 0x2c2c2c002c2c2c00, 0xececec00ececec00, 0xb3b3b300b3b3b300, 0x2727270027272700, 0xc0c0c000c0c0c000, 0xe5e5e500e5e5e500,
			0xe4e4e400e4e4e400, 0x8585850085858500, 0x5757570057575700, 0x3535350035353500, 0xeaeaea00eaeaea00, 0x0c0c0c000c0c0c00, 0xaeaeae00aeaeae00, 0x4141410041414100,
			0x2323230023232300, 0xefefef00efefef00, 0x6b6b6b006b6b6b00, 0x9393930093939300, 0x4545450045454500, 0x1919190019191900, 0xa5a5a500a5a5a500, 0x2121210021212100,
			0xededed00ededed00, 0x0e0e0e000e0e0e00, 0x4f4f4f004f4f4f00, 0x4e4e4e004e4e4e00, 0x1d1d1d001d1d1d00, 0x6565650065656500, 0x9292920092929200, 0xbdbdbd00bdbdbd00,
			0x8686860086868600, 0xb8b8b800b8b8b800, 0xafafaf00afafaf00, 0x8f8f8f008f8f8f00, 0x7c7c7c007c7c7c00, 0xebebeb00ebebeb00, 0x1f1f1f001f1f1f00, 0xcecece00cecece00,
			0x3e3e3e003e3e3e00, 0x3030300030303000, 0xdcdcdc00dcdcdc00, 0x5f5f5f005f5f5f00, 0x5e5e5e005e5e5e00, 0xc5c5c500c5c5c500, 0x0b0b0b000b0b0b00, 0x1a1a1a001a1a1a00,
			0xa6a6a600a6a6a600, 0xe1e1e100e1e1e100, 0x3939390039393900, 0xcacaca00cacaca00, 0xd5d5d500d5d5d500, 0x4747470047474700, 0x5d5d5d005d5d5d00, 0x3d3d3d003d3d3d00,
			0xd9d9d900d9d9d900, 0x0101010001010100, 0x5a5a5a005a5a5a00, 0xd6d6d600d6d6d600, 0x5151510051515100, 0x5656560056565600, 0x6c6c6c006c6c6c00, 0x4d4d4d004d4d4d00,
			0x8b8b8b008b8b8b00, 0x0d0d0d000d0d0d00, 0x9a9a9a009a9a9a00, 0x6666660066666600, 0xfbfbfb00fbfbfb00, 0xcccccc00cccccc00, 0xb0b0b000b0b0b000, 0x2d2d2d002d2d2d00,
			0x7474740074747400, 0x1212120012121200, 0x2b2b2b002b2b2b00, 0x2020200020202000, 0xf0f0f000f0f0f000, 0xb1b1b100b1b1b100, 0x8484840084848400, 0x9999990099999900,
			0xdfdfdf00dfdfdf00, 0x4c4c4c004c4c4c00, 0xcbcbcb00cbcbcb00, 0xc2c2c200c2c2c200, 0x3434340034343400, 0x7e7e7e007e7e7e00, 0x7676760076767600, 0x0505050005050500,
			0x6d6d6d006d6d6d00, 0xb7b7b700b7b7b700, 0xa9a9a900a9a9a900, 0x3131310031313100, 0xd1d1d100d1d1d100, 0x1717170017171700, 0x0404040004040400, 0xd7d7d700d7d7d700,
			0x1414140014141400, 0x5858580058585800, 0x3a3a3a003a3a3a00, 0x6161610061616100, 0xdedede00dedede00, 0x1b1b1b001b1b1b00, 0x1111110011111100, 0x1c1c1c001c1c1c00,
			0x3232320032323200, 0x0f0f0f000f0f0f00, 0x9c9c9c009c9c9c00, 0x1616160016161600, 0x5353530053535300, 0x1818180018181800, 0xf2f2f200f2f2f200, 0x2222220022222200,
			0xfefefe00fefefe00, 0x4444440044444400, 0xcfcfcf00cfcfcf00, 0xb2b2b200b2b2b200, 0xc3c3c300c3c3c300, 0xb5b5b500b5b5b500, 0x7a7a7a007a7a7a00, 0x9191910091919100,
			0x2424240024242400, 0x0808080008080800, 0xe8e8e800e8e8e800, 0xa8a8a800a8a8a800, 0x6060600060606000, 0xfcfcfc00fcfcfc00, 0x6969690069696900, 0x5050500050505000,
			0xaaaaaa00aaaaaa00, 0xd0d0d000d0d0d000, 0xa0a0a000a0a0a000, 0x7d7d7d007d7d7d00, 0xa1a1a100a1a1a100, 0x8989890089898900, 0x6262620062626200, 0x9797970097979700,
			0x5454540054545400, 0x5b5b5b005b5b5b00, 0x1e1e1e001e1e1e00, 0x9595950095959500, 0xe0e0e000e0e0e000, 0xffffff00ffffff00, 0x6464640064646400, 0xd2d2d200d2d2d200,
			0x1010100010101000, 0xc4c4c400c4c4c400, 0x0000000000000000, 0x4848480048484800, 0xa3a3a300a3a3a300, 0xf7f7f700f7f7f700, 0x7575750075757500, 0xdbdbdb00dbdbdb00,
			0x8a8a8a008a8a8a00, 0x0303030003030300, 0xe6e6e600e6e6e600, 0xdadada00dadada00, 0x0909090009090900, 0x3f3f3f003f3f3f00, 0xdddddd00dddddd00, 0x9494940094949400,
			0x8787870087878700, 0x5c5c5c005c5c5c00, 0x8383830083838300, 0x0202020002020200, 0xcdcdcd00cdcdcd00, 0x4a4a4a004a4a4a00, 0x9090900090909000, 0x3333330033333300,
			0x7373730073737300, 0x6767670067676700, 0xf6f6f600f6f6f600, 0xf3f3f300f3f3f300, 0x9d9d9d009d9d9d00, 0x7f7f7f007f7f7f00, 0xbfbfbf00bfbfbf00, 0xe2e2e200e2e2e200,
			0x5252520052525200, 0x9b9b9b009b9b9b00, 0xd8d8d800d8d8d800, 0x2626260026262600, 0xc8c8c800c8c8c800, 0x3737370037373700, 0xc6c6c600c6c6c600, 0x3b3b3b003b3b3b00,
			0x8181810081818100, 0x9696960096969600, 0x6f6f6f006f6f6f00, 0x4b4b4b004b4b4b00, 0x1313130013131300, 0xbebebe00bebebe00, 0x6363630063636300, 0x2e2e2e002e2e2e00,
			0xe9e9e900e9e9e900, 0x7979790079797900, 0xa7a7a700a7a7a700, 0x8c8c8c008c8c8c00, 0x9f9f9f009f9f9f00, 0x6e6e6e006e6e6e00, 0xbcbcbc00bcbcbc00, 0x8e8e8e008e8e8e00,
			0x2929290029292900, 0xf5f5f500f5f5f500, 0xf9f9f900f9f9f900, 0xb6b6b600b6b6b600, 0x2f2f2f002f2f2f00, 0xfdfdfd00fdfdfd00, 0xb4b4b400b4b4b400, 0x5959590059595900,
			0x7878780078787800, 0x9898980098989800, 0x0606060006060600, 0x6a6a6a006a6a6a00, 0xe7e7e700e7e7e700, 0x4646460046464600, 0x7171710071717100, 0xbababa00bababa00,
			0xd4d4d400d4d4d400, 0x2525250025252500, 0xababab00ababab00, 0x4242420042424200, 0x8888880088888800, 0xa2a2a200a2a2a200, 0x8d8d8d008d8d8d00, 0xfafafa00fafafa00,
			0x7272720072727200, 0x0707070007070700, 0xb9b9b900b9b9b900, 0x5555550055555500, 0xf8f8f800f8f8f800, 0xeeeeee00eeeeee00, 0xacacac00acacac00, 0x0a0a0a000a0a0a00,
			0x3636360036363600, 0x4949490049494900, 0x2a2a2a002a2a2a00, 0x6868680068686800, 0x3c3c3c003c3c3c00, 0x3838380038383800, 0xf1f1f100f1f1f100, 0xa4a4a400a4a4a400,
			0x4040400040404000, 0x2828280028282800, 0xd3d3d300d3d3d300, 0x7b7b7b007b7b7b00, 0xbbbbbb00bbbbbb00, 0xc9c9c900c9c9c900, 0x4343430043434300, 0xc1c1c100c1c1c100,
			0x1515150015151500, 0xe3e3e300e3e3e300, 0xadadad00adadad00, 0xf4f4f400f4f4f400, 0x7777770077777700, 0xc7c7c700c7c7c700, 0x8080800080808000, 0x9e9e9e009e9e9e00
		}
	};

	const uint64 KS[] = { 0xA09E667F3BCC908B, 0xB67AE8584CAA73B2, 0xC6EF372FE94F82BE, 0x54FF53A5F1D36F1C, 0x10E527FADE682D1D, 0xB05688C2B3E6C1FD };

	VC_INLINE uint64 F(uint64 x, uint64 k)
	{
		uint64 t = x ^ k;
		return S[0][(t >> 56) & 0xFF] ^ S[1][(t >> 48) & 0xFF] ^ S[2][(t >> 40) & 0xFF] ^ S[3][(t >> 32) & 0xFF] ^ S[4][(t >> 24) & 0xFF] ^ S[5][(t >> 16) & 0xFF] ^ S[6][(t >> 8) & 0xFF] ^ S[7][t & 0xFF];
	}

	VC_INLINE uint64 FL(uint64 x, uint64 k)
	{
		uint32 xl = (uint32)(x >> 32);
		uint32 xr = (uint32)(x);
		uint32 kl = (uint32)(k >> 32);
		uint32 kr = (uint32)(k);

		uint32 yr = rotl32(xl & kl, 1) ^ xr;
		uint32 yl = (yr | kr) ^ xl;
		return (((uint64)(yl)) << 32) | yr;
	}

	VC_INLINE uint64 FL1(uint64 y, uint64 k)
	{
		uint32 yl = (uint32)(y >> 32);
		uint32 yr = (uint32)(y);
		uint32 kl = (uint32)(k >> 32);
		uint32 kr = (uint32)(k);

		uint32 xl = (yr | kr) ^ yl;
		uint32 xr = rotl32(xl & kl, 1) ^ yr;
		return (((uint64)(xl)) << 32) | xr;
	}

	VC_INLINE uint64 rotl128l(uint64 l, uint64 r, int n)
	{
		return (l << n) | (r >> (64 - n));
	}

	VC_INLINE uint64 rotl128r(uint64 l, uint64 r, int n)
	{
		return (r << n) | (l >> (64 - n));
	}

	
void camellia_set_key(const unsigned __int8 key[], unsigned __int8 *ksPtr)
{
	uint64 *ks = (uint64 *) ksPtr;
	uint64 kll = bswap_64(*((uint64*)key));
	uint64 klr = bswap_64(*((uint64*)(key + 8)));
	uint64 krl = bswap_64(*((uint64*)(key + 16)));
	uint64 krr = bswap_64(*((uint64*)(key + 24)));

#ifdef CPPCRYPTO_DEBUG
	printf("kl: %016I64x %016I64x\n", kll, klr);
	printf("kr: %016I64x %016I64x\n", krl, krr);
#endif

	uint64 kal = kll ^ krl;
	uint64 kar = klr ^ krr;
	uint64 lp = kal;
	uint64 kbl, kbr;

	kal = kar ^ F(kal, KS[0]);
	kar = kal;
	kal = lp ^ F(kal, KS[1]);
	kal ^= kll;
	kar ^= klr;

	lp = kal;
	kal = kar ^ F(kal, KS[2]);
	kar = kal;
	kal = lp ^ F(kal, KS[3]);

#ifdef CPPCRYPTO_DEBUG
	printf("ka: %016I64x %016I64x\n", kal, kar);
#endif
	kbl = kal ^ krl;
	kbr = kar ^ krr;
	lp = kbl;
	kbl = kbr ^ F(kbl, KS[4]);
	kbr = kbl;
	kbl = lp ^ F(kbl, KS[5]);
#ifdef CPPCRYPTO_DEBUG
	printf("kb: %016I64x %016I64x\n", kbl, kbr);
#endif

	ks[0] = kll;
	ks[1] = klr;
	ks[2] = kbl;
	ks[3] = kbr;
	ks[4] = rotl128l(krl, krr, 15);
	ks[5] = rotl128r(krl, krr, 15);
	ks[6] = rotl128l(kal, kar, 15);
	ks[7] = rotl128r(kal, kar, 15);
	ks[8] = rotl128l(krl, krr, 30);
	ks[9] = rotl128r(krl, krr, 30);

	ks[10] = rotl128l(kbl, kbr, 30);
	ks[11] = rotl128r(kbl, kbr, 30);
	ks[12] = rotl128l(kll, klr, 45);
	ks[13] = rotl128r(kll, klr, 45);
	ks[14] = rotl128l(kal, kar, 45);
	ks[15] = rotl128r(kal, kar, 45);
	ks[16] = rotl128l(kll, klr, 60);
	ks[17] = rotl128r(kll, klr, 60);

	ks[18] = rotl128l(krl, krr, 60);
	ks[19] = rotl128r(krl, krr, 60);
	ks[20] = rotl128l(kbl, kbr, 60);
	ks[21] = rotl128r(kbl, kbr, 60);
	ks[22] = rotl128r(kll, klr, 13);
	ks[23] = rotl128l(kll, klr, 13);
	ks[24] = rotl128r(kal, kar, 13);
	ks[25] = rotl128l(kal, kar, 13);

	ks[26] = ks[9]; // rotl128r(krl, krr, 30);
	ks[27] = ks[8]; // rotl128l(krl, krr, 30);
	ks[28] = rotl128r(kal, kar, 30);
	ks[29] = rotl128l(kal, kar, 30);
	ks[30] = rotl128r(kll, klr, 47);
	ks[31] = rotl128l(kll, klr, 47);
	ks[32] = rotl128r(kbl, kbr, 47);
	ks[33] = rotl128l(kbl, kbr, 47);

#ifdef CPPCRYPTO_DEBUG
	for (int i = 0; i < 34; i++)
		printf("ks[%d]: %016I64x\n", i, ks[i]);
#endif
}

void camellia_encrypt(const unsigned __int8 *in, unsigned __int8 *out, unsigned __int8 *ksPtr)
{
	uint64 *ks = (uint64 *) ksPtr;
	uint64 l = bswap_64(*((uint64*)in)) ^ ks[0];
	uint64 r = bswap_64(*((uint64*)(in + 8))) ^ ks[1];

#ifdef CPPCRYPTO_DEBUG
	printf("r0: %016I64x %016I64x\n", l, r);
#endif
	// r = 1
	uint64 lp = l;
	l = r ^ F(l, ks[2]);
	// r = lp;
#ifdef CPPCRYPTO_DEBUG
	printf("r1: %016I64x %016I64x\n", l, lp);
#endif

	// r = 2
	r = l;
	l = lp ^ F(l, ks[3]);
#ifdef CPPCRYPTO_DEBUG
	printf("r2: %016I64x %016I64x\n", l, r);
#endif

	// r = 3
	lp = l;
	l = r ^ F(l, ks[4]);
#ifdef CPPCRYPTO_DEBUG
	printf("r3: %016I64x %016I64x\n", l, lp);
#endif

	// r = 4
	r = l;
	l = lp ^ F(l, ks[5]);
#ifdef CPPCRYPTO_DEBUG
	printf("r4: %016I64x %016I64x\n", l, r);
#endif

	// r = 5
	lp = l;
	l = r ^ F(l, ks[6]);
#ifdef CPPCRYPTO_DEBUG
	printf("r5: %016I64x %016I64x\n", l, lp);
#endif

	// r = 6
	r = l;
	l = lp ^ F(l, ks[7]);
	l = FL(l, ks[8]);
	r = FL1(r, ks[9]);
#ifdef CPPCRYPTO_DEBUG
	printf("r6: %016I64x %016I64x\n", l, r);
#endif

	// r = 7
	lp = l;
	l = r ^ F(l, ks[10]);

	// r = 8
	r = l;
	l = lp ^ F(l, ks[11]);

	// r = 9
	lp = l;
	l = r ^ F(l, ks[12]);

	// r = 10
	r = l;
	l = lp ^ F(l, ks[13]);

	// r = 11
	lp = l;
	l = r ^ F(l, ks[14]);

	// r = 12
	r = l;
	l = lp ^ F(l, ks[15]);
	l = FL(l, ks[16]);
	r = FL1(r, ks[17]);

	// r = 13
	lp = l;
	l = r ^ F(l, ks[18]);

	// r = 14
	r = l;
	l = lp ^ F(l, ks[19]);

	// r = 15
	lp = l;
	l = r ^ F(l, ks[20]);

	// r = 16
	r = l;
	l = lp ^ F(l, ks[21]);

	// r = 17
	lp = l;
	l = r ^ F(l, ks[22]);

	// r = 18
	r = l;
	l = lp ^ F(l, ks[23]);
	l = FL(l, ks[24]);
	r = FL1(r, ks[25]);

	// r = 19
	lp = l;
	l = r ^ F(l, ks[26]);

	// r = 20
	r = l;
	l = lp ^ F(l, ks[27]);

	// r = 21
	lp = l;
	l = r ^ F(l, ks[28]);

	// r = 22
	r = l;
	l = lp ^ F(l, ks[29]);

	// r = 23
	lp = l;
	l = r ^ F(l, ks[30]);

	// r = 24
	r = l;
	l = lp ^ F(l, ks[31]);

	r ^= ks[32];
	l ^= ks[33];

	*(uint64*)out = bswap_64(r);
	*(uint64*)(out + 8) = bswap_64(l);
}


void camellia_decrypt(const unsigned __int8 *in,  unsigned __int8 *out, unsigned __int8 *ksPtr)
{
	uint64 *ks = (uint64 *) ksPtr;
	uint64 r = bswap_64(*((uint64*)in)) ^ ks[32];
	uint64 l = bswap_64(*((uint64*)(in + 8))) ^ ks[33];

#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", l, r);
#endif

	// r = 24
	uint64 rp = r;
	r = l ^ F(r, ks[31]);

#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", rp, r);
#endif

	// r = 23
	l = r;
	r = rp ^ F(r, ks[30]);
#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", l, r);
#endif

	// r = 22
	rp = r;
	r = l ^ F(r, ks[29]);
#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", rp, r);
#endif

	// r = 21
	l = r;
	r = rp ^ F(r, ks[28]);
#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", l, r);
#endif

	// r = 20
	rp = r;
	r = l ^ F(r, ks[27]);
#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", rp, r);
#endif

	// r = 19
	l = r;
	r = rp ^ F(r, ks[26]);
#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", l, r);
#endif
	l = FL1(l, ks[24]);
	r = FL(r, ks[25]);

#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPTFL: %016I64x %016I64x\n", l, r);
#endif

	// r = 18
	rp = r;
	r = l ^ F(r, ks[23]);
#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT18: %016I64x %016I64x\n", rp, r);
#endif

	// r = 17
	l = r;
	r = rp ^ F(r, ks[22]);

#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", l, r);
#endif

	// r = 16
	rp = r;
	r = l ^ F(r, ks[21]);

#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", rp, r);
#endif

	// r = 15
	l = r;
	r = rp ^ F(r, ks[20]);

#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", l, r);
#endif

	// r = 14
	rp = r;
	r = l ^ F(r, ks[19]);

#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", rp, r);
#endif

	// r = 13
	l = r;
	r = rp ^ F(r, ks[18]);
	l = FL1(l, ks[16]);
	r = FL(r, ks[17]);

#ifdef CPPCRYPTO_DEBUG
	printf("DECRYPT: %016I64x %016I64x\n", l, r);
#endif

	// r = 12
	rp = r;
	r = l ^ F(r, ks[15]);

	// r = 11
	l = r;
	r = rp ^ F(r, ks[14]);

	// r = 10
	rp = r;
	r = l ^ F(r, ks[13]);

	// r = 9
	l = r;
	r = rp ^ F(r, ks[12]);

	// r = 8
	rp = r;
	r = l ^ F(r, ks[11]);

	// r = 7
	l = r;
	r = rp ^ F(r, ks[10]);
	l = FL1(l, ks[8]);
	r = FL(r, ks[9]);

	// r = 6
	rp = r;
	r = l ^ F(r, ks[7]);

	// r = 5
	l = r;
	r = rp ^ F(r, ks[6]);

	// r = 4
	rp = r;
	r = l ^ F(r, ks[5]);

	// r = 3
	l = r;
	r = rp ^ F(r, ks[4]);

	// r = 2
	rp = r;
	r = l ^ F(r, ks[3]);

	// r = 1
	l = r;
	r = rp ^ F(r, ks[2]);

	// r = 0
	l ^= ks[0];
	r ^= ks[1];

	*(uint64*)out = bswap_64(l);
	*(uint64*)(out + 8) = bswap_64(r);
}