00001
00002
00003
00004 #include "pch.h"
00005 #include "cast.h"
00006 #include "misc.h"
00007
00008 NAMESPACE_BEGIN(CryptoPP)
00009
00010
00011 #define U8a(x) GETBYTE(x,3)
00012 #define U8b(x) GETBYTE(x,2)
00013 #define U8c(x) GETBYTE(x,1)
00014 #define U8d(x) GETBYTE(x,0)
00015
00016
00017 #define f1(l, r, km, kr) \
00018 t = rotlVariable(km + r, kr); \
00019 l ^= ((S[0][U8a(t)] ^ S[1][U8b(t)]) - \
00020 S[2][U8c(t)]) + S[3][U8d(t)];
00021 #define f2(l, r, km, kr) \
00022 t = rotlVariable(km ^ r, kr); \
00023 l ^= ((S[0][U8a(t)] - S[1][U8b(t)]) + \
00024 S[2][U8c(t)]) ^ S[3][U8d(t)];
00025 #define f3(l, r, km, kr) \
00026 t = rotlVariable(km - r, kr); \
00027 l ^= ((S[0][U8a(t)] + S[1][U8b(t)]) ^ \
00028 S[2][U8c(t)]) - S[3][U8d(t)];
00029
00030 #define F1(l, r, i, j) f1(l, r, K[i], K[i+j])
00031 #define F2(l, r, i, j) f2(l, r, K[i], K[i+j])
00032 #define F3(l, r, i, j) f3(l, r, K[i], K[i+j])
00033
00034 typedef BlockGetAndPut<word32, BigEndian> Block;
00035
00036 void CAST128::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00037 {
00038 word32 t, l, r;
00039
00040
00041 Block::Get(inBlock)(l)(r);
00042
00043 F1(l, r, 0, 16);
00044 F2(r, l, 1, 16);
00045 F3(l, r, 2, 16);
00046 F1(r, l, 3, 16);
00047 F2(l, r, 4, 16);
00048 F3(r, l, 5, 16);
00049 F1(l, r, 6, 16);
00050 F2(r, l, 7, 16);
00051 F3(l, r, 8, 16);
00052 F1(r, l, 9, 16);
00053 F2(l, r, 10, 16);
00054 F3(r, l, 11, 16);
00055
00056 if (!reduced) {
00057 F1(l, r, 12, 16);
00058 F2(r, l, 13, 16);
00059 F3(l, r, 14, 16);
00060 F1(r, l, 15, 16);
00061 }
00062
00063 Block::Put(xorBlock, outBlock)(r)(l);
00064 }
00065
00066 void CAST128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00067 {
00068 word32 t, l, r;
00069
00070
00071 Block::Get(inBlock)(r)(l);
00072
00073 if (!reduced) {
00074 F1(r, l, 15, 16);
00075 F3(l, r, 14, 16);
00076 F2(r, l, 13, 16);
00077 F1(l, r, 12, 16);
00078 }
00079 F3(r, l, 11, 16);
00080 F2(l, r, 10, 16);
00081 F1(r, l, 9, 16);
00082 F3(l, r, 8, 16);
00083 F2(r, l, 7, 16);
00084 F1(l, r, 6, 16);
00085 F3(r, l, 5, 16);
00086 F2(l, r, 4, 16);
00087 F1(r, l, 3, 16);
00088 F3(l, r, 2, 16);
00089 F2(r, l, 1, 16);
00090 F1(l, r, 0, 16);
00091
00092 Block::Put(xorBlock, outBlock)(l)(r);
00093
00094 t = l = r = 0;
00095 }
00096
00097 void CAST128::Base::UncheckedSetKey(CipherDir dir, const byte *userKey, unsigned int keylength)
00098 {
00099 AssertValidKeyLength(keylength);
00100
00101 reduced = (keylength <= 10);
00102
00103 word32 X[4], Z[4];
00104 GetUserKey(BIG_ENDIAN_ORDER, X, 4, userKey, keylength);
00105
00106 #define x(i) GETBYTE(X[i/4], 3-i%4)
00107 #define z(i) GETBYTE(Z[i/4], 3-i%4)
00108
00109 unsigned int i;
00110 for (i=0; i<=16; i+=16)
00111 {
00112
00113 Z[0] = X[0] ^ S[4][x(0xD)] ^ S[5][x(0xF)] ^ S[6][x(0xC)] ^ S[7][x(0xE)] ^ S[6][x(0x8)];
00114 Z[1] = X[2] ^ S[4][z(0x0)] ^ S[5][z(0x2)] ^ S[6][z(0x1)] ^ S[7][z(0x3)] ^ S[7][x(0xA)];
00115 Z[2] = X[3] ^ S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[4][x(0x9)];
00116 Z[3] = X[1] ^ S[4][z(0xA)] ^ S[5][z(0x9)] ^ S[6][z(0xB)] ^ S[7][z(0x8)] ^ S[5][x(0xB)];
00117 K[i+0] = S[4][z(0x8)] ^ S[5][z(0x9)] ^ S[6][z(0x7)] ^ S[7][z(0x6)] ^ S[4][z(0x2)];
00118 K[i+1] = S[4][z(0xA)] ^ S[5][z(0xB)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[5][z(0x6)];
00119 K[i+2] = S[4][z(0xC)] ^ S[5][z(0xD)] ^ S[6][z(0x3)] ^ S[7][z(0x2)] ^ S[6][z(0x9)];
00120 K[i+3] = S[4][z(0xE)] ^ S[5][z(0xF)] ^ S[6][z(0x1)] ^ S[7][z(0x0)] ^ S[7][z(0xC)];
00121 X[0] = Z[2] ^ S[4][z(0x5)] ^ S[5][z(0x7)] ^ S[6][z(0x4)] ^ S[7][z(0x6)] ^ S[6][z(0x0)];
00122 X[1] = Z[0] ^ S[4][x(0x0)] ^ S[5][x(0x2)] ^ S[6][x(0x1)] ^ S[7][x(0x3)] ^ S[7][z(0x2)];
00123 X[2] = Z[1] ^ S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[4][z(0x1)];
00124 X[3] = Z[3] ^ S[4][x(0xA)] ^ S[5][x(0x9)] ^ S[6][x(0xB)] ^ S[7][x(0x8)] ^ S[5][z(0x3)];
00125 K[i+4] = S[4][x(0x3)] ^ S[5][x(0x2)] ^ S[6][x(0xC)] ^ S[7][x(0xD)] ^ S[4][x(0x8)];
00126 K[i+5] = S[4][x(0x1)] ^ S[5][x(0x0)] ^ S[6][x(0xE)] ^ S[7][x(0xF)] ^ S[5][x(0xD)];
00127 K[i+6] = S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x8)] ^ S[7][x(0x9)] ^ S[6][x(0x3)];
00128 K[i+7] = S[4][x(0x5)] ^ S[5][x(0x4)] ^ S[6][x(0xA)] ^ S[7][x(0xB)] ^ S[7][x(0x7)];
00129 Z[0] = X[0] ^ S[4][x(0xD)] ^ S[5][x(0xF)] ^ S[6][x(0xC)] ^ S[7][x(0xE)] ^ S[6][x(0x8)];
00130 Z[1] = X[2] ^ S[4][z(0x0)] ^ S[5][z(0x2)] ^ S[6][z(0x1)] ^ S[7][z(0x3)] ^ S[7][x(0xA)];
00131 Z[2] = X[3] ^ S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[4][x(0x9)];
00132 Z[3] = X[1] ^ S[4][z(0xA)] ^ S[5][z(0x9)] ^ S[6][z(0xB)] ^ S[7][z(0x8)] ^ S[5][x(0xB)];
00133 K[i+8] = S[4][z(0x3)] ^ S[5][z(0x2)] ^ S[6][z(0xC)] ^ S[7][z(0xD)] ^ S[4][z(0x9)];
00134 K[i+9] = S[4][z(0x1)] ^ S[5][z(0x0)] ^ S[6][z(0xE)] ^ S[7][z(0xF)] ^ S[5][z(0xC)];
00135 K[i+10] = S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x8)] ^ S[7][z(0x9)] ^ S[6][z(0x2)];
00136 K[i+11] = S[4][z(0x5)] ^ S[5][z(0x4)] ^ S[6][z(0xA)] ^ S[7][z(0xB)] ^ S[7][z(0x6)];
00137 X[0] = Z[2] ^ S[4][z(0x5)] ^ S[5][z(0x7)] ^ S[6][z(0x4)] ^ S[7][z(0x6)] ^ S[6][z(0x0)];
00138 X[1] = Z[0] ^ S[4][x(0x0)] ^ S[5][x(0x2)] ^ S[6][x(0x1)] ^ S[7][x(0x3)] ^ S[7][z(0x2)];
00139 X[2] = Z[1] ^ S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[4][z(0x1)];
00140 X[3] = Z[3] ^ S[4][x(0xA)] ^ S[5][x(0x9)] ^ S[6][x(0xB)] ^ S[7][x(0x8)] ^ S[5][z(0x3)];
00141 K[i+12] = S[4][x(0x8)] ^ S[5][x(0x9)] ^ S[6][x(0x7)] ^ S[7][x(0x6)] ^ S[4][x(0x3)];
00142 K[i+13] = S[4][x(0xA)] ^ S[5][x(0xB)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[5][x(0x7)];
00143 K[i+14] = S[4][x(0xC)] ^ S[5][x(0xD)] ^ S[6][x(0x3)] ^ S[7][x(0x2)] ^ S[6][x(0x8)];
00144 K[i+15] = S[4][x(0xE)] ^ S[5][x(0xF)] ^ S[6][x(0x1)] ^ S[7][x(0x0)] ^ S[7][x(0xD)];
00145 }
00146
00147 for (i=16; i<32; i++)
00148 K[i] &= 0x1f;
00149 }
00150
00151
00152
00153 const word32 CAST256::Base::t_m[8][24]={
00154 0x5a827999, 0xd151d6a1, 0x482133a9, 0xbef090b1, 0x35bfedb9, 0xac8f4ac1,
00155 0x235ea7c9, 0x9a2e04d1, 0x10fd61d9, 0x87ccbee1, 0xfe9c1be9, 0x756b78f1,
00156 0xec3ad5f9, 0x630a3301, 0xd9d99009, 0x50a8ed11, 0xc7784a19, 0x3e47a721,
00157 0xb5170429, 0x2be66131, 0xa2b5be39, 0x19851b41, 0x90547849, 0x0723d551,
00158 0xc95c653a, 0x402bc242, 0xb6fb1f4a, 0x2dca7c52, 0xa499d95a, 0x1b693662,
00159 0x9238936a, 0x0907f072, 0x7fd74d7a, 0xf6a6aa82, 0x6d76078a, 0xe4456492,
00160 0x5b14c19a, 0xd1e41ea2, 0x48b37baa, 0xbf82d8b2, 0x365235ba, 0xad2192c2,
00161 0x23f0efca, 0x9ac04cd2, 0x118fa9da, 0x885f06e2, 0xff2e63ea, 0x75fdc0f2,
00162 0x383650db, 0xaf05ade3, 0x25d50aeb, 0x9ca467f3, 0x1373c4fb, 0x8a432203,
00163 0x01127f0b, 0x77e1dc13, 0xeeb1391b, 0x65809623, 0xdc4ff32b, 0x531f5033,
00164 0xc9eead3b, 0x40be0a43, 0xb78d674b, 0x2e5cc453, 0xa52c215b, 0x1bfb7e63,
00165 0x92cadb6b, 0x099a3873, 0x8069957b, 0xf738f283, 0x6e084f8b, 0xe4d7ac93,
00166 0xa7103c7c, 0x1ddf9984, 0x94aef68c, 0x0b7e5394, 0x824db09c, 0xf91d0da4,
00167 0x6fec6aac, 0xe6bbc7b4, 0x5d8b24bc, 0xd45a81c4, 0x4b29decc, 0xc1f93bd4,
00168 0x38c898dc, 0xaf97f5e4, 0x266752ec, 0x9d36aff4, 0x14060cfc, 0x8ad56a04,
00169 0x01a4c70c, 0x78742414, 0xef43811c, 0x6612de24, 0xdce23b2c, 0x53b19834,
00170 0x15ea281d, 0x8cb98525, 0x0388e22d, 0x7a583f35, 0xf1279c3d, 0x67f6f945,
00171 0xdec6564d, 0x5595b355, 0xcc65105d, 0x43346d65, 0xba03ca6d, 0x30d32775,
00172 0xa7a2847d, 0x1e71e185, 0x95413e8d, 0x0c109b95, 0x82dff89d, 0xf9af55a5,
00173 0x707eb2ad, 0xe74e0fb5, 0x5e1d6cbd, 0xd4ecc9c5, 0x4bbc26cd, 0xc28b83d5,
00174 0x84c413be, 0xfb9370c6, 0x7262cdce, 0xe9322ad6, 0x600187de, 0xd6d0e4e6,
00175 0x4da041ee, 0xc46f9ef6, 0x3b3efbfe, 0xb20e5906, 0x28ddb60e, 0x9fad1316,
00176 0x167c701e, 0x8d4bcd26, 0x041b2a2e, 0x7aea8736, 0xf1b9e43e, 0x68894146,
00177 0xdf589e4e, 0x5627fb56, 0xccf7585e, 0x43c6b566, 0xba96126e, 0x31656f76,
00178 0xf39dff5f, 0x6a6d5c67, 0xe13cb96f, 0x580c1677, 0xcedb737f, 0x45aad087,
00179 0xbc7a2d8f, 0x33498a97, 0xaa18e79f, 0x20e844a7, 0x97b7a1af, 0x0e86feb7,
00180 0x85565bbf, 0xfc25b8c7, 0x72f515cf, 0xe9c472d7, 0x6093cfdf, 0xd7632ce7,
00181 0x4e3289ef, 0xc501e6f7, 0x3bd143ff, 0xb2a0a107, 0x296ffe0f, 0xa03f5b17,
00182 0x6277eb00, 0xd9474808, 0x5016a510, 0xc6e60218, 0x3db55f20, 0xb484bc28,
00183 0x2b541930, 0xa2237638, 0x18f2d340, 0x8fc23048, 0x06918d50, 0x7d60ea58,
00184 0xf4304760, 0x6affa468, 0xe1cf0170, 0x589e5e78, 0xcf6dbb80, 0x463d1888,
00185 0xbd0c7590, 0x33dbd298, 0xaaab2fa0, 0x217a8ca8, 0x9849e9b0, 0x0f1946b8
00186 };
00187
00188 const unsigned int CAST256::Base::t_r[8][24]={
00189 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11,
00190 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28,
00191 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13,
00192 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30,
00193 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15,
00194 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0,
00195 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17,
00196 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2
00197 };
00198
00199 #define Q(i) \
00200 F1(block[2],block[3],8*i+4,-4); \
00201 F2(block[1],block[2],8*i+5,-4); \
00202 F3(block[0],block[1],8*i+6,-4); \
00203 F1(block[3],block[0],8*i+7,-4);
00204
00205 #define QBar(i) \
00206 F1(block[3],block[0],8*i+7,-4); \
00207 F3(block[0],block[1],8*i+6,-4); \
00208 F2(block[1],block[2],8*i+5,-4); \
00209 F1(block[2],block[3],8*i+4,-4);
00210
00211
00212
00213
00214 void CAST256::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00215 {
00216 word32 t, block[4];
00217 Block::Get(inBlock)(block[0])(block[1])(block[2])(block[3]);
00218
00219
00220 Q(0);
00221 Q(1);
00222 Q(2);
00223 Q(3);
00224 Q(4);
00225 Q(5);
00226
00227
00228 QBar(6);
00229 QBar(7);
00230 QBar(8);
00231 QBar(9);
00232 QBar(10);
00233 QBar(11);
00234
00235 Block::Put(xorBlock, outBlock)(block[0])(block[1])(block[2])(block[3]);
00236 }
00237
00238
00239
00240 void CAST256::Base::Omega(int i, word32 kappa[8])
00241 {
00242 word32 t;
00243
00244 f1(kappa[6],kappa[7],t_m[0][i],t_r[0][i]);
00245 f2(kappa[5],kappa[6],t_m[1][i],t_r[1][i]);
00246 f3(kappa[4],kappa[5],t_m[2][i],t_r[2][i]);
00247 f1(kappa[3],kappa[4],t_m[3][i],t_r[3][i]);
00248 f2(kappa[2],kappa[3],t_m[4][i],t_r[4][i]);
00249 f3(kappa[1],kappa[2],t_m[5][i],t_r[5][i]);
00250 f1(kappa[0],kappa[1],t_m[6][i],t_r[6][i]);
00251 f2(kappa[7],kappa[0],t_m[7][i],t_r[7][i]);
00252 }
00253
00254 void CAST256::Base::UncheckedSetKey(CipherDir dir, const byte *userKey, unsigned int keylength)
00255 {
00256 AssertValidKeyLength(keylength);
00257
00258 word32 kappa[8];
00259 GetUserKey(BIG_ENDIAN_ORDER, kappa, 8, userKey, keylength);
00260
00261 for(int i=0; i<12; ++i)
00262 {
00263 Omega(2*i,kappa);
00264 Omega(2*i+1,kappa);
00265
00266 K[8*i]=kappa[0] & 31;
00267 K[8*i+1]=kappa[2] & 31;
00268 K[8*i+2]=kappa[4] & 31;
00269 K[8*i+3]=kappa[6] & 31;
00270 K[8*i+4]=kappa[7];
00271 K[8*i+5]=kappa[5];
00272 K[8*i+6]=kappa[3];
00273 K[8*i+7]=kappa[1];
00274 }
00275
00276 if (dir == DECRYPTION)
00277 {
00278 for(int j=0; j<6; ++j)
00279 {
00280 for(int i=0; i<4; ++i)
00281 {
00282 int i1=8*j+i;
00283 int i2=8*(11-j)+i;
00284
00285 assert(i1<i2);
00286
00287 std::swap(K[i1],K[i2]);
00288 std::swap(K[i1+4],K[i2+4]);
00289 }
00290 }
00291 }
00292
00293 memset(kappa, 0, sizeof(kappa));
00294 }
00295
00296 NAMESPACE_END