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