camellia.cpp

00001 // camellia.cpp - by Kevin Springle, 2003
00002 // This code is hereby placed in the public domain.
00003 
00004 #include "pch.h"
00005 
00006 #ifdef WORD64_AVAILABLE
00007 
00008 #include "camellia.h"
00009 #include "misc.h"
00010 
00011 NAMESPACE_BEGIN(CryptoPP)
00012 
00013 // Define internal Camellia function macros
00014 
00015 inline word64 Camellia::Base::F(word64 X)
00016 {
00017         word32 t1 = (word32)(X >> 32);
00018         word32 t2 = (word32)(X & 0xFFFFFFFFL);
00019         t2=     (s2[GETBYTE(t2, 3)] << 24) |
00020                 (s3[GETBYTE(t2, 2)] << 16) |
00021                 (s4[GETBYTE(t2, 1)] <<  8) |
00022                 (s1[GETBYTE(t2, 0)]);
00023         t1=     (s1[GETBYTE(t1, 3)] << 24) |
00024                 (s2[GETBYTE(t1, 2)] << 16) |
00025                 (s3[GETBYTE(t1, 1)] <<  8) |
00026                 (s4[GETBYTE(t1, 0)]);
00027         t1 ^= rotlFixed(t2, 8);
00028         t2 ^= rotlFixed(t1, 16);
00029         t1 ^= rotlFixed(t2, 24);
00030         t2 ^= rotlFixed(t1, 24);
00031         return ((word64)t2 << 32) | (word64)t1;
00032 }
00033 
00034 #define ROUND2(Xp, K1, K2) \
00035         { (Xp)[1] ^= F((Xp)[0] ^ K1); (Xp)[0] ^= F((Xp)[1] ^ K2); }
00036 
00037 inline void Camellia::Base::FLlayer(word64 *x, word64 K1, word64 K2)
00038 {
00039         word32 Xl = (word32)(x[0] >> 32);
00040         word32 Xr = (word32)(x[0] & 0xFFFFFFFFL);
00041         Xr ^= rotlFixed(Xl & (word32)(K1 >> 32), 1);
00042         Xl ^= (Xr | (word32)(K1 & 0xFFFFFFFFL));
00043     x[0] = ((word64)Xl << 32) | (word64)Xr;
00044 
00045         Xl = (word32)(x[1] >> 32);
00046         Xr = (word32)(x[1] & 0xFFFFFFFFL);
00047         Xl ^= (Xr | (word32)(K2 & 0xFFFFFFFFL));
00048         Xr ^= rotlFixed(Xl & (word32)(K2 >> 32), 1);
00049     x[1] = ((word64)Xl << 32) | (word64)Xr;
00050 }
00051 
00052 inline void rotl128(word64 *x, unsigned int bits)
00053 {
00054         word64 temp = x[0] >> (64 - bits);
00055         x[0] = (x[0] << bits) | (x[1] >> (64 - bits));
00056         x[1] = (x[1] << bits) | temp;
00057 }
00058 
00059 void Camellia::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &)
00060 {
00061         AssertValidKeyLength(keylen);
00062 
00063         m_rounds = (keylen >= 24) ? 4 : 3;
00064         unsigned int kslen = (8 * m_rounds + 2);
00065         m_key.New(8 * kslen);
00066         word64 *ks = m_key;
00067 
00068         FixedSizeSecBlock<word64, 32> keyword;
00069         word64 *kw = keyword;
00070 
00071 #define KL      (kw+0)
00072 #define KR      (kw+2)
00073 #define KA      (kw+4)
00074 #define KB      (kw+6)
00075 
00076         if (keylen == 16)
00077         {
00078                 GetUserKey(BIG_ENDIAN_ORDER, kw, 2, key, keylen);
00079                 KA[0] = KL[0];
00080                 KA[1] = KL[1];
00081         }
00082         else
00083         {
00084                 if (keylen == 24)
00085                 {
00086                         GetUserKey(BIG_ENDIAN_ORDER, kw, 3, key, keylen);
00087                         KR[1] = ~KR[0];
00088                 }
00089                 else
00090                 {
00091                         GetUserKey(BIG_ENDIAN_ORDER, kw, 4, key, keylen);
00092                 }
00093                 KA[0] = KL[0] ^ KR[0];
00094                 KA[1] = KL[1] ^ KR[1];
00095         }
00096         ROUND2(KA, W64LIT(0xA09E667F3BCC908B), W64LIT(0xB67AE8584CAA73B2));
00097         KA[0] ^= KL[0];
00098         KA[1] ^= KL[1];
00099         ROUND2(KA, W64LIT(0xC6EF372FE94F82BE), W64LIT(0x54FF53A5F1D36F1C));
00100 
00101         if (keylen == 16)
00102         {
00103                 ks[0] = KL[0]; ks[1] = KL[1];
00104                 rotl128(KL, 15);
00105                 ks[4] = KL[0]; ks[5] = KL[1];
00106                 rotl128(KL, 30);
00107                 ks[10] = KL[0]; ks[11] = KL[1];
00108                 rotl128(KL, 15);
00109                 ks[13] = KL[1];
00110                 rotl128(KL, 17);
00111                 ks[16] = KL[0]; ks[17] = KL[1];
00112                 rotl128(KL, 17);
00113                 ks[18] = KL[0]; ks[19] = KL[1];
00114                 rotl128(KL, 17);
00115                 ks[22] = KL[0]; ks[23] = KL[1];
00116 
00117                 ks[2] = KA[0]; ks[3] = KA[1];
00118                 rotl128(KA, 15);
00119                 ks[6] = KA[0]; ks[7] = KA[1];
00120                 rotl128(KA, 15);
00121                 ks[8] = KA[0]; ks[9] = KA[1];
00122                 rotl128(KA, 15);
00123                 ks[12] = KA[0];
00124                 rotl128(KA, 15);
00125                 ks[14] = KA[0]; ks[15] = KA[1];
00126                 rotl128(KA, 34);
00127                 ks[20] = KA[0]; ks[21] = KA[1];
00128                 rotl128(KA, 17);
00129                 ks[24] = KA[0]; ks[25] = KA[1];
00130         }
00131         else
00132         {
00133                 KB[0] = KA[0] ^ KR[0];
00134                 KB[1] = KA[1] ^ KR[1];
00135                 ROUND2(KB, W64LIT(0x10E527FADE682D1D), W64LIT(0xB05688C2B3E6C1FD));
00136 
00137                 ks[0] = KL[0]; ks[1] = KL[1];
00138                 rotl128(KL, 45);
00139                 ks[12] = KL[0]; ks[13] = KL[1];
00140                 rotl128(KL, 15);
00141                 ks[16] = KL[0]; ks[17] = KL[1];
00142                 rotl128(KL, 17);
00143                 ks[22] = KL[0]; ks[23] = KL[1];
00144                 rotl128(KL, 34);
00145                 ks[30] = KL[0]; ks[31] = KL[1];
00146 
00147                 rotl128(KR, 15);
00148                 ks[4] = KR[0]; ks[5] = KR[1];
00149                 rotl128(KR, 15);
00150                 ks[8] = KR[0]; ks[9] = KR[1];
00151                 rotl128(KR, 30);
00152                 ks[18] = KR[0]; ks[19] = KR[1];
00153                 rotl128(KR, 34);
00154                 ks[26] = KR[0]; ks[27] = KR[1];
00155 
00156                 rotl128(KA, 15);
00157                 ks[6] = KA[0]; ks[7] = KA[1];
00158                 rotl128(KA, 30);
00159                 ks[14] = KA[0]; ks[15] = KA[1];
00160                 rotl128(KA, 32);
00161                 ks[24] = KA[0]; ks[25] = KA[1];
00162                 rotl128(KA, 17);
00163                 ks[28] = KA[0]; ks[29] = KA[1];
00164 
00165                 ks[2] = KB[0]; ks[3] = KB[1];
00166                 rotl128(KB, 30);
00167                 ks[10] = KB[0]; ks[11] = KB[1];
00168                 rotl128(KB, 30);
00169                 ks[20] = KB[0]; ks[21] = KB[1];
00170                 rotl128(KB, 51);
00171                 ks[32] = KB[0]; ks[33] = KB[1];
00172         }
00173 
00174         if (!IsForwardTransformation()) // reverse key schedule order
00175         {
00176                 std::swap(ks[0], ks[kslen-2]);
00177                 std::swap(ks[1], ks[kslen-1]);
00178                 for (unsigned int i=2; i<kslen/2; i++)
00179                 {
00180                         std::swap(ks[i], ks[kslen-1-i]);
00181                 }
00182         }
00183 }
00184 
00185 typedef BlockGetAndPut<word64, BigEndian> Block;
00186 
00187 void Camellia::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00188 {
00189         FixedSizeSecBlock<word64, 16> mb;
00190         word64 *m = mb;
00191         const word64 *ks = m_key;
00192 
00193         Block::Get(inBlock)(m[0])(m[1]);
00194 
00195         m[0] ^= ks[0];
00196         m[1] ^= ks[1];
00197         ks += 2;
00198         for (unsigned int i = m_rounds; i > 0; --i)
00199         {
00200                 ROUND2(m, ks[0], ks[1]);
00201                 ROUND2(m, ks[2], ks[3]);
00202                 ROUND2(m, ks[4], ks[5]);
00203                 if (i != 1)
00204                 {
00205                         FLlayer(m, ks[6], ks[7]);
00206                         ks += 8;
00207                 }
00208                 else
00209                 {
00210                         m[0] ^= ks[7];
00211                         m[1] ^= ks[6];
00212                 }
00213         }
00214 
00215         Block::Put(xorBlock, outBlock)(m[1])(m[0]);
00216 }
00217 
00218 // The Camellia s-boxes
00219 
00220 const byte Camellia::Base::s1[256] =
00221 {
00222         112,130,44,236,179,39,192,229,228,133,87,53,234,12,174,65,
00223         35,239,107,147,69,25,165,33,237,14,79,78,29,101,146,189,
00224         134,184,175,143,124,235,31,206,62,48,220,95,94,197,11,26,
00225         166,225,57,202,213,71,93,61,217,1,90,214,81,86,108,77,
00226         139,13,154,102,251,204,176,45,116,18,43,32,240,177,132,153,
00227         223,76,203,194,52,126,118,5,109,183,169,49,209,23,4,215,
00228         20,88,58,97,222,27,17,28,50,15,156,22,83,24,242,34,
00229         254,68,207,178,195,181,122,145,36,8,232,168,96,252,105,80,
00230         170,208,160,125,161,137,98,151,84,91,30,149,224,255,100,210,
00231         16,196,0,72,163,247,117,219,138,3,230,218,9,63,221,148,
00232         135,92,131,2,205,74,144,51,115,103,246,243,157,127,191,226,
00233         82,155,216,38,200,55,198,59,129,150,111,75,19,190,99,46,
00234         233,121,167,140,159,110,188,142,41,245,249,182,47,253,180,89,
00235         120,152,6,106,231,70,113,186,212,37,171,66,136,162,141,250,
00236         114,7,185,85,248,238,172,10,54,73,42,104,60,56,241,164,
00237         64,40,211,123,187,201,67,193,21,227,173,244,119,199,128,158
00238 };
00239 
00240 const byte Camellia::Base::s2[256] =
00241 {
00242         224,5,88,217,103,78,129,203,201,11,174,106,213,24,93,130,
00243         70,223,214,39,138,50,75,66,219,28,158,156,58,202,37,123,
00244         13,113,95,31,248,215,62,157,124,96,185,190,188,139,22,52,
00245         77,195,114,149,171,142,186,122,179,2,180,173,162,172,216,154,
00246         23,26,53,204,247,153,97,90,232,36,86,64,225,99,9,51,
00247         191,152,151,133,104,252,236,10,218,111,83,98,163,46,8,175,
00248         40,176,116,194,189,54,34,56,100,30,57,44,166,48,229,68,
00249         253,136,159,101,135,107,244,35,72,16,209,81,192,249,210,160,
00250         85,161,65,250,67,19,196,47,168,182,60,43,193,255,200,165,
00251         32,137,0,144,71,239,234,183,21,6,205,181,18,126,187,41,
00252         15,184,7,4,155,148,33,102,230,206,237,231,59,254,127,197,
00253         164,55,177,76,145,110,141,118,3,45,222,150,38,125,198,92,
00254         211,242,79,25,63,220,121,29,82,235,243,109,94,251,105,178,
00255         240,49,12,212,207,140,226,117,169,74,87,132,17,69,27,245,
00256         228,14,115,170,241,221,89,20,108,146,84,208,120,112,227,73,
00257         128,80,167,246,119,147,134,131,42,199,91,233,238,143,1,61
00258 };
00259 
00260 const byte Camellia::Base::s3[256] =
00261 {
00262         56,65,22,118,217,147,96,242,114,194,171,154,117,6,87,160,
00263         145,247,181,201,162,140,210,144,246,7,167,39,142,178,73,222,
00264         67,92,215,199,62,245,143,103,31,24,110,175,47,226,133,13,
00265         83,240,156,101,234,163,174,158,236,128,45,107,168,43,54,166,
00266         197,134,77,51,253,102,88,150,58,9,149,16,120,216,66,204,
00267         239,38,229,97,26,63,59,130,182,219,212,152,232,139,2,235,
00268         10,44,29,176,111,141,136,14,25,135,78,11,169,12,121,17,
00269         127,34,231,89,225,218,61,200,18,4,116,84,48,126,180,40,
00270         85,104,80,190,208,196,49,203,42,173,15,202,112,255,50,105,
00271         8,98,0,36,209,251,186,237,69,129,115,109,132,159,238,74,
00272         195,46,193,1,230,37,72,153,185,179,123,249,206,191,223,113,
00273         41,205,108,19,100,155,99,157,192,75,183,165,137,95,177,23,
00274         244,188,211,70,207,55,94,71,148,250,252,91,151,254,90,172,
00275         60,76,3,53,243,35,184,93,106,146,213,33,68,81,198,125,
00276         57,131,220,170,124,119,86,5,27,164,21,52,30,28,248,82,
00277         32,20,233,189,221,228,161,224,138,241,214,122,187,227,64,79
00278 };
00279 
00280 const byte Camellia::Base::s4[256] =
00281 {
00282         112,44,179,192,228,87,234,174,35,107,69,165,237,79,29,146,
00283         134,175,124,31,62,220,94,11,166,57,213,93,217,90,81,108,
00284         139,154,251,176,116,43,240,132,223,203,52,118,109,169,209,4,
00285         20,58,222,17,50,156,83,242,254,207,195,122,36,232,96,105,
00286         170,160,161,98,84,30,224,100,16,0,163,117,138,230,9,221,
00287         135,131,205,144,115,246,157,191,82,216,200,198,129,111,19,99,
00288         233,167,159,188,41,249,47,180,120,6,231,113,212,171,136,141,
00289         114,185,248,172,54,42,60,241,64,211,187,67,21,173,119,128,
00290         130,236,39,229,133,53,12,65,239,147,25,33,14,78,101,189,
00291         184,143,235,206,48,95,197,26,225,202,71,61,1,214,86,77,
00292         13,102,204,45,18,32,177,153,76,194,126,5,183,49,23,215,
00293         88,97,27,28,15,22,24,34,68,178,181,145,8,168,252,80,
00294         208,125,137,151,91,149,255,210,196,72,247,219,3,218,63,148,
00295         92,2,74,51,103,243,127,226,155,38,55,59,150,75,190,46,
00296         121,140,110,142,245,182,253,89,152,106,70,186,37,66,162,250,
00297         7,85,238,10,73,104,56,164,40,123,201,193,227,244,199,158
00298 };
00299 
00300 NAMESPACE_END
00301 
00302 #endif // WORD64_AVAILABLE

Generated on Sat Dec 23 02:07:06 2006 for Crypto++ by  doxygen 1.5.1-p1