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