Botan  1.11.15
src/lib/block/cast/cast256.cpp
Go to the documentation of this file.
00001 /*
00002 * CAST-256
00003 * (C) 1999-2007 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/block_utils.h>
00009 #include <botan/cast256.h>
00010 #include <botan/internal/cast_sboxes.h>
00011 
00012 namespace Botan {
00013 
00014 BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(CAST_256, "CAST-256");
00015 
00016 namespace {
00017 
00018 /*
00019 * CAST-256 Round Type 1
00020 */
00021 void round1(u32bit& out, u32bit in, u32bit mask, u32bit rot)
00022    {
00023    u32bit temp = rotate_left(mask + in, rot);
00024    out  ^= (CAST_SBOX1[get_byte(0, temp)] ^ CAST_SBOX2[get_byte(1, temp)]) -
00025             CAST_SBOX3[get_byte(2, temp)] + CAST_SBOX4[get_byte(3, temp)];
00026    }
00027 
00028 /*
00029 * CAST-256 Round Type 2
00030 */
00031 void round2(u32bit& out, u32bit in, u32bit mask, u32bit rot)
00032    {
00033    u32bit temp = rotate_left(mask ^ in, rot);
00034    out  ^= (CAST_SBOX1[get_byte(0, temp)]  - CAST_SBOX2[get_byte(1, temp)] +
00035             CAST_SBOX3[get_byte(2, temp)]) ^ CAST_SBOX4[get_byte(3, temp)];
00036    }
00037 
00038 /*
00039 * CAST-256 Round Type 3
00040 */
00041 void round3(u32bit& out, u32bit in, u32bit mask, u32bit rot)
00042    {
00043    u32bit temp = rotate_left(mask - in, rot);
00044    out  ^= ((CAST_SBOX1[get_byte(0, temp)]  + CAST_SBOX2[get_byte(1, temp)]) ^
00045              CAST_SBOX3[get_byte(2, temp)]) - CAST_SBOX4[get_byte(3, temp)];
00046    }
00047 
00048 }
00049 
00050 /*
00051 * CAST-256 Encryption
00052 */
00053 void CAST_256::encrypt_n(const byte in[], byte out[], size_t blocks) const
00054    {
00055    for(size_t i = 0; i != blocks; ++i)
00056       {
00057       u32bit A = load_be<u32bit>(in, 0);
00058       u32bit B = load_be<u32bit>(in, 1);
00059       u32bit C = load_be<u32bit>(in, 2);
00060       u32bit D = load_be<u32bit>(in, 3);
00061 
00062       round1(C, D, MK[ 0], RK[ 0]); round2(B, C, MK[ 1], RK[ 1]);
00063       round3(A, B, MK[ 2], RK[ 2]); round1(D, A, MK[ 3], RK[ 3]);
00064       round1(C, D, MK[ 4], RK[ 4]); round2(B, C, MK[ 5], RK[ 5]);
00065       round3(A, B, MK[ 6], RK[ 6]); round1(D, A, MK[ 7], RK[ 7]);
00066       round1(C, D, MK[ 8], RK[ 8]); round2(B, C, MK[ 9], RK[ 9]);
00067       round3(A, B, MK[10], RK[10]); round1(D, A, MK[11], RK[11]);
00068       round1(C, D, MK[12], RK[12]); round2(B, C, MK[13], RK[13]);
00069       round3(A, B, MK[14], RK[14]); round1(D, A, MK[15], RK[15]);
00070       round1(C, D, MK[16], RK[16]); round2(B, C, MK[17], RK[17]);
00071       round3(A, B, MK[18], RK[18]); round1(D, A, MK[19], RK[19]);
00072       round1(C, D, MK[20], RK[20]); round2(B, C, MK[21], RK[21]);
00073       round3(A, B, MK[22], RK[22]); round1(D, A, MK[23], RK[23]);
00074       round1(D, A, MK[27], RK[27]); round3(A, B, MK[26], RK[26]);
00075       round2(B, C, MK[25], RK[25]); round1(C, D, MK[24], RK[24]);
00076       round1(D, A, MK[31], RK[31]); round3(A, B, MK[30], RK[30]);
00077       round2(B, C, MK[29], RK[29]); round1(C, D, MK[28], RK[28]);
00078       round1(D, A, MK[35], RK[35]); round3(A, B, MK[34], RK[34]);
00079       round2(B, C, MK[33], RK[33]); round1(C, D, MK[32], RK[32]);
00080       round1(D, A, MK[39], RK[39]); round3(A, B, MK[38], RK[38]);
00081       round2(B, C, MK[37], RK[37]); round1(C, D, MK[36], RK[36]);
00082       round1(D, A, MK[43], RK[43]); round3(A, B, MK[42], RK[42]);
00083       round2(B, C, MK[41], RK[41]); round1(C, D, MK[40], RK[40]);
00084       round1(D, A, MK[47], RK[47]); round3(A, B, MK[46], RK[46]);
00085       round2(B, C, MK[45], RK[45]); round1(C, D, MK[44], RK[44]);
00086 
00087       store_be(out, A, B, C, D);
00088 
00089       in += BLOCK_SIZE;
00090       out += BLOCK_SIZE;
00091       }
00092    }
00093 
00094 /*
00095 * CAST-256 Decryption
00096 */
00097 void CAST_256::decrypt_n(const byte in[], byte out[], size_t blocks) const
00098    {
00099    for(size_t i = 0; i != blocks; ++i)
00100       {
00101       u32bit A = load_be<u32bit>(in, 0);
00102       u32bit B = load_be<u32bit>(in, 1);
00103       u32bit C = load_be<u32bit>(in, 2);
00104       u32bit D = load_be<u32bit>(in, 3);
00105 
00106       round1(C, D, MK[44], RK[44]); round2(B, C, MK[45], RK[45]);
00107       round3(A, B, MK[46], RK[46]); round1(D, A, MK[47], RK[47]);
00108       round1(C, D, MK[40], RK[40]); round2(B, C, MK[41], RK[41]);
00109       round3(A, B, MK[42], RK[42]); round1(D, A, MK[43], RK[43]);
00110       round1(C, D, MK[36], RK[36]); round2(B, C, MK[37], RK[37]);
00111       round3(A, B, MK[38], RK[38]); round1(D, A, MK[39], RK[39]);
00112       round1(C, D, MK[32], RK[32]); round2(B, C, MK[33], RK[33]);
00113       round3(A, B, MK[34], RK[34]); round1(D, A, MK[35], RK[35]);
00114       round1(C, D, MK[28], RK[28]); round2(B, C, MK[29], RK[29]);
00115       round3(A, B, MK[30], RK[30]); round1(D, A, MK[31], RK[31]);
00116       round1(C, D, MK[24], RK[24]); round2(B, C, MK[25], RK[25]);
00117       round3(A, B, MK[26], RK[26]); round1(D, A, MK[27], RK[27]);
00118       round1(D, A, MK[23], RK[23]); round3(A, B, MK[22], RK[22]);
00119       round2(B, C, MK[21], RK[21]); round1(C, D, MK[20], RK[20]);
00120       round1(D, A, MK[19], RK[19]); round3(A, B, MK[18], RK[18]);
00121       round2(B, C, MK[17], RK[17]); round1(C, D, MK[16], RK[16]);
00122       round1(D, A, MK[15], RK[15]); round3(A, B, MK[14], RK[14]);
00123       round2(B, C, MK[13], RK[13]); round1(C, D, MK[12], RK[12]);
00124       round1(D, A, MK[11], RK[11]); round3(A, B, MK[10], RK[10]);
00125       round2(B, C, MK[ 9], RK[ 9]); round1(C, D, MK[ 8], RK[ 8]);
00126       round1(D, A, MK[ 7], RK[ 7]); round3(A, B, MK[ 6], RK[ 6]);
00127       round2(B, C, MK[ 5], RK[ 5]); round1(C, D, MK[ 4], RK[ 4]);
00128       round1(D, A, MK[ 3], RK[ 3]); round3(A, B, MK[ 2], RK[ 2]);
00129       round2(B, C, MK[ 1], RK[ 1]); round1(C, D, MK[ 0], RK[ 0]);
00130 
00131       store_be(out, A, B, C, D);
00132 
00133       in += BLOCK_SIZE;
00134       out += BLOCK_SIZE;
00135       }
00136    }
00137 
00138 /*
00139 * CAST-256 Key Schedule
00140 */
00141 void CAST_256::key_schedule(const byte key[], size_t length)
00142    {
00143    static const u32bit KEY_MASK[192] = {
00144       0x5A827999, 0xC95C653A, 0x383650DB, 0xA7103C7C, 0x15EA281D, 0x84C413BE,
00145       0xF39DFF5F, 0x6277EB00, 0xD151D6A1, 0x402BC242, 0xAF05ADE3, 0x1DDF9984,
00146       0x8CB98525, 0xFB9370C6, 0x6A6D5C67, 0xD9474808, 0x482133A9, 0xB6FB1F4A,
00147       0x25D50AEB, 0x94AEF68C, 0x0388E22D, 0x7262CDCE, 0xE13CB96F, 0x5016A510,
00148       0xBEF090B1, 0x2DCA7C52, 0x9CA467F3, 0x0B7E5394, 0x7A583F35, 0xE9322AD6,
00149       0x580C1677, 0xC6E60218, 0x35BFEDB9, 0xA499D95A, 0x1373C4FB, 0x824DB09C,
00150       0xF1279C3D, 0x600187DE, 0xCEDB737F, 0x3DB55F20, 0xAC8F4AC1, 0x1B693662,
00151       0x8A432203, 0xF91D0DA4, 0x67F6F945, 0xD6D0E4E6, 0x45AAD087, 0xB484BC28,
00152       0x235EA7C9, 0x9238936A, 0x01127F0B, 0x6FEC6AAC, 0xDEC6564D, 0x4DA041EE,
00153       0xBC7A2D8F, 0x2B541930, 0x9A2E04D1, 0x0907F072, 0x77E1DC13, 0xE6BBC7B4,
00154       0x5595B355, 0xC46F9EF6, 0x33498A97, 0xA2237638, 0x10FD61D9, 0x7FD74D7A,
00155       0xEEB1391B, 0x5D8B24BC, 0xCC65105D, 0x3B3EFBFE, 0xAA18E79F, 0x18F2D340,
00156       0x87CCBEE1, 0xF6A6AA82, 0x65809623, 0xD45A81C4, 0x43346D65, 0xB20E5906,
00157       0x20E844A7, 0x8FC23048, 0xFE9C1BE9, 0x6D76078A, 0xDC4FF32B, 0x4B29DECC,
00158       0xBA03CA6D, 0x28DDB60E, 0x97B7A1AF, 0x06918D50, 0x756B78F1, 0xE4456492,
00159       0x531F5033, 0xC1F93BD4, 0x30D32775, 0x9FAD1316, 0x0E86FEB7, 0x7D60EA58,
00160       0xEC3AD5F9, 0x5B14C19A, 0xC9EEAD3B, 0x38C898DC, 0xA7A2847D, 0x167C701E,
00161       0x85565BBF, 0xF4304760, 0x630A3301, 0xD1E41EA2, 0x40BE0A43, 0xAF97F5E4,
00162       0x1E71E185, 0x8D4BCD26, 0xFC25B8C7, 0x6AFFA468, 0xD9D99009, 0x48B37BAA,
00163       0xB78D674B, 0x266752EC, 0x95413E8D, 0x041B2A2E, 0x72F515CF, 0xE1CF0170,
00164       0x50A8ED11, 0xBF82D8B2, 0x2E5CC453, 0x9D36AFF4, 0x0C109B95, 0x7AEA8736,
00165       0xE9C472D7, 0x589E5E78, 0xC7784A19, 0x365235BA, 0xA52C215B, 0x14060CFC,
00166       0x82DFF89D, 0xF1B9E43E, 0x6093CFDF, 0xCF6DBB80, 0x3E47A721, 0xAD2192C2,
00167       0x1BFB7E63, 0x8AD56A04, 0xF9AF55A5, 0x68894146, 0xD7632CE7, 0x463D1888,
00168       0xB5170429, 0x23F0EFCA, 0x92CADB6B, 0x01A4C70C, 0x707EB2AD, 0xDF589E4E,
00169       0x4E3289EF, 0xBD0C7590, 0x2BE66131, 0x9AC04CD2, 0x099A3873, 0x78742414,
00170       0xE74E0FB5, 0x5627FB56, 0xC501E6F7, 0x33DBD298, 0xA2B5BE39, 0x118FA9DA,
00171       0x8069957B, 0xEF43811C, 0x5E1D6CBD, 0xCCF7585E, 0x3BD143FF, 0xAAAB2FA0,
00172       0x19851B41, 0x885F06E2, 0xF738F283, 0x6612DE24, 0xD4ECC9C5, 0x43C6B566,
00173       0xB2A0A107, 0x217A8CA8, 0x90547849, 0xFF2E63EA, 0x6E084F8B, 0xDCE23B2C,
00174       0x4BBC26CD, 0xBA96126E, 0x296FFE0F, 0x9849E9B0, 0x0723D551, 0x75FDC0F2,
00175       0xE4D7AC93, 0x53B19834, 0xC28B83D5, 0x31656F76, 0xA03F5B17, 0x0F1946B8 };
00176 
00177    static const byte KEY_ROT[32] = {
00178       0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0A, 0x1B, 0x0C,
00179       0x1D, 0x0E, 0x1F, 0x10, 0x01, 0x12, 0x03, 0x14, 0x05, 0x16,
00180       0x07, 0x18, 0x09, 0x1A, 0x0B, 0x1C, 0x0D, 0x1E, 0x0F, 0x00,
00181       0x11, 0x02 };
00182 
00183    MK.resize(48);
00184    RK.resize(48);
00185 
00186    secure_vector<u32bit> K(8);
00187    for(size_t i = 0; i != length; ++i)
00188       K[i/4] = (K[i/4] << 8) + key[i];
00189 
00190    u32bit A = K[0], B = K[1], C = K[2], D = K[3],
00191           E = K[4], F = K[5], G = K[6], H = K[7];
00192 
00193    for(size_t i = 0; i != 48; i += 4)
00194       {
00195       round1(G, H, KEY_MASK[4*i+ 0], KEY_ROT[(4*i+ 0) % 32]);
00196       round2(F, G, KEY_MASK[4*i+ 1], KEY_ROT[(4*i+ 1) % 32]);
00197       round3(E, F, KEY_MASK[4*i+ 2], KEY_ROT[(4*i+ 2) % 32]);
00198       round1(D, E, KEY_MASK[4*i+ 3], KEY_ROT[(4*i+ 3) % 32]);
00199       round2(C, D, KEY_MASK[4*i+ 4], KEY_ROT[(4*i+ 4) % 32]);
00200       round3(B, C, KEY_MASK[4*i+ 5], KEY_ROT[(4*i+ 5) % 32]);
00201       round1(A, B, KEY_MASK[4*i+ 6], KEY_ROT[(4*i+ 6) % 32]);
00202       round2(H, A, KEY_MASK[4*i+ 7], KEY_ROT[(4*i+ 7) % 32]);
00203       round1(G, H, KEY_MASK[4*i+ 8], KEY_ROT[(4*i+ 8) % 32]);
00204       round2(F, G, KEY_MASK[4*i+ 9], KEY_ROT[(4*i+ 9) % 32]);
00205       round3(E, F, KEY_MASK[4*i+10], KEY_ROT[(4*i+10) % 32]);
00206       round1(D, E, KEY_MASK[4*i+11], KEY_ROT[(4*i+11) % 32]);
00207       round2(C, D, KEY_MASK[4*i+12], KEY_ROT[(4*i+12) % 32]);
00208       round3(B, C, KEY_MASK[4*i+13], KEY_ROT[(4*i+13) % 32]);
00209       round1(A, B, KEY_MASK[4*i+14], KEY_ROT[(4*i+14) % 32]);
00210       round2(H, A, KEY_MASK[4*i+15], KEY_ROT[(4*i+15) % 32]);
00211 
00212       RK[i  ] = (A % 32);
00213       RK[i+1] = (C % 32);
00214       RK[i+2] = (E % 32);
00215       RK[i+3] = (G % 32);
00216       MK[i  ] = H;
00217       MK[i+1] = F;
00218       MK[i+2] = D;
00219       MK[i+3] = B;
00220       }
00221    }
00222 
00223 void CAST_256::clear()
00224    {
00225    zap(MK);
00226    zap(RK);
00227    }
00228 
00229 }