Botan  1.11.15
src/lib/block/twofish/twofish.cpp
Go to the documentation of this file.
00001 /*
00002 * Twofish
00003 * (C) 1999-2007 Jack Lloyd
00004 *
00005 * The key schedule implemenation is based on a public domain
00006 * implementation by Matthew Skala
00007 *
00008 * Botan is released under the Simplified BSD License (see license.txt)
00009 */
00010 
00011 #include <botan/internal/block_utils.h>
00012 #include <botan/twofish.h>
00013 
00014 namespace Botan {
00015 
00016 BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Twofish);
00017 
00018 /*
00019 * Twofish Encryption
00020 */
00021 void Twofish::encrypt_n(const byte in[], byte out[], size_t blocks) const
00022    {
00023    for(size_t i = 0; i != blocks; ++i)
00024       {
00025       u32bit A = load_le<u32bit>(in, 0) ^ RK[0];
00026       u32bit B = load_le<u32bit>(in, 1) ^ RK[1];
00027       u32bit C = load_le<u32bit>(in, 2) ^ RK[2];
00028       u32bit D = load_le<u32bit>(in, 3) ^ RK[3];
00029 
00030       for(size_t j = 0; j != 16; j += 2)
00031          {
00032          u32bit X, Y;
00033 
00034          X = SB[    get_byte(3, A)] ^ SB[256+get_byte(2, A)] ^
00035              SB[512+get_byte(1, A)] ^ SB[768+get_byte(0, A)];
00036          Y = SB[    get_byte(0, B)] ^ SB[256+get_byte(3, B)] ^
00037              SB[512+get_byte(2, B)] ^ SB[768+get_byte(1, B)];
00038          X += Y;
00039          Y += X + RK[2*j + 9];
00040          X += RK[2*j + 8];
00041 
00042          C = rotate_right(C ^ X, 1);
00043          D = rotate_left(D, 1) ^ Y;
00044 
00045          X = SB[    get_byte(3, C)] ^ SB[256+get_byte(2, C)] ^
00046              SB[512+get_byte(1, C)] ^ SB[768+get_byte(0, C)];
00047          Y = SB[    get_byte(0, D)] ^ SB[256+get_byte(3, D)] ^
00048              SB[512+get_byte(2, D)] ^ SB[768+get_byte(1, D)];
00049          X += Y;
00050          Y += X + RK[2*j + 11];
00051          X += RK[2*j + 10];
00052 
00053          A = rotate_right(A ^ X, 1);
00054          B = rotate_left(B, 1) ^ Y;
00055          }
00056 
00057       C ^= RK[4];
00058       D ^= RK[5];
00059       A ^= RK[6];
00060       B ^= RK[7];
00061 
00062       store_le(out, C, D, A, B);
00063 
00064       in += BLOCK_SIZE;
00065       out += BLOCK_SIZE;
00066       }
00067    }
00068 
00069 /*
00070 * Twofish Decryption
00071 */
00072 void Twofish::decrypt_n(const byte in[], byte out[], size_t blocks) const
00073    {
00074    for(size_t i = 0; i != blocks; ++i)
00075       {
00076       u32bit A = load_le<u32bit>(in, 0) ^ RK[4];
00077       u32bit B = load_le<u32bit>(in, 1) ^ RK[5];
00078       u32bit C = load_le<u32bit>(in, 2) ^ RK[6];
00079       u32bit D = load_le<u32bit>(in, 3) ^ RK[7];
00080 
00081       for(size_t j = 0; j != 16; j += 2)
00082          {
00083          u32bit X, Y;
00084 
00085          X = SB[    get_byte(3, A)] ^ SB[256+get_byte(2, A)] ^
00086              SB[512+get_byte(1, A)] ^ SB[768+get_byte(0, A)];
00087          Y = SB[    get_byte(0, B)] ^ SB[256+get_byte(3, B)] ^
00088              SB[512+get_byte(2, B)] ^ SB[768+get_byte(1, B)];
00089          X += Y;
00090          Y += X + RK[39 - 2*j];
00091          X += RK[38 - 2*j];
00092 
00093          C = rotate_left(C, 1) ^ X;
00094          D = rotate_right(D ^ Y, 1);
00095 
00096          X = SB[    get_byte(3, C)] ^ SB[256+get_byte(2, C)] ^
00097              SB[512+get_byte(1, C)] ^ SB[768+get_byte(0, C)];
00098          Y = SB[    get_byte(0, D)] ^ SB[256+get_byte(3, D)] ^
00099              SB[512+get_byte(2, D)] ^ SB[768+get_byte(1, D)];
00100          X += Y;
00101          Y += X + RK[37 - 2*j];
00102          X += RK[36 - 2*j];
00103 
00104          A = rotate_left(A, 1) ^ X;
00105          B = rotate_right(B ^ Y, 1);
00106          }
00107 
00108       C ^= RK[0];
00109       D ^= RK[1];
00110       A ^= RK[2];
00111       B ^= RK[3];
00112 
00113       store_le(out, C, D, A, B);
00114 
00115       in += BLOCK_SIZE;
00116       out += BLOCK_SIZE;
00117       }
00118    }
00119 
00120 /*
00121 * Twofish Key Schedule
00122 */
00123 void Twofish::key_schedule(const byte key[], size_t length)
00124    {
00125    SB.resize(1024);
00126    RK.resize(40);
00127 
00128    secure_vector<byte> S(16);
00129 
00130    for(size_t i = 0; i != length; ++i)
00131       rs_mul(&S[4*(i/8)], key[i], i);
00132 
00133    if(length == 16)
00134       {
00135       for(size_t i = 0; i != 256; ++i)
00136          {
00137          SB[    i] = MDS0[Q0[Q0[i]^S[ 0]]^S[ 4]];
00138          SB[256+i] = MDS1[Q0[Q1[i]^S[ 1]]^S[ 5]];
00139          SB[512+i] = MDS2[Q1[Q0[i]^S[ 2]]^S[ 6]];
00140          SB[768+i] = MDS3[Q1[Q1[i]^S[ 3]]^S[ 7]];
00141          }
00142 
00143       for(size_t i = 0; i != 40; i += 2)
00144          {
00145          u32bit X = MDS0[Q0[Q0[i  ]^key[ 8]]^key[ 0]] ^
00146                     MDS1[Q0[Q1[i  ]^key[ 9]]^key[ 1]] ^
00147                     MDS2[Q1[Q0[i  ]^key[10]]^key[ 2]] ^
00148                     MDS3[Q1[Q1[i  ]^key[11]]^key[ 3]];
00149          u32bit Y = MDS0[Q0[Q0[i+1]^key[12]]^key[ 4]] ^
00150                     MDS1[Q0[Q1[i+1]^key[13]]^key[ 5]] ^
00151                     MDS2[Q1[Q0[i+1]^key[14]]^key[ 6]] ^
00152                     MDS3[Q1[Q1[i+1]^key[15]]^key[ 7]];
00153          Y = rotate_left(Y, 8);
00154          X += Y; Y += X;
00155 
00156          RK[i] = X;
00157          RK[i+1] = rotate_left(Y, 9);
00158          }
00159       }
00160    else if(length == 24)
00161       {
00162       for(size_t i = 0; i != 256; ++i)
00163          {
00164          SB[    i] = MDS0[Q0[Q0[Q1[i]^S[ 0]]^S[ 4]]^S[ 8]];
00165          SB[256+i] = MDS1[Q0[Q1[Q1[i]^S[ 1]]^S[ 5]]^S[ 9]];
00166          SB[512+i] = MDS2[Q1[Q0[Q0[i]^S[ 2]]^S[ 6]]^S[10]];
00167          SB[768+i] = MDS3[Q1[Q1[Q0[i]^S[ 3]]^S[ 7]]^S[11]];
00168          }
00169 
00170       for(size_t i = 0; i != 40; i += 2)
00171          {
00172          u32bit X = MDS0[Q0[Q0[Q1[i  ]^key[16]]^key[ 8]]^key[ 0]] ^
00173                     MDS1[Q0[Q1[Q1[i  ]^key[17]]^key[ 9]]^key[ 1]] ^
00174                     MDS2[Q1[Q0[Q0[i  ]^key[18]]^key[10]]^key[ 2]] ^
00175                     MDS3[Q1[Q1[Q0[i  ]^key[19]]^key[11]]^key[ 3]];
00176          u32bit Y = MDS0[Q0[Q0[Q1[i+1]^key[20]]^key[12]]^key[ 4]] ^
00177                     MDS1[Q0[Q1[Q1[i+1]^key[21]]^key[13]]^key[ 5]] ^
00178                     MDS2[Q1[Q0[Q0[i+1]^key[22]]^key[14]]^key[ 6]] ^
00179                     MDS3[Q1[Q1[Q0[i+1]^key[23]]^key[15]]^key[ 7]];
00180          Y = rotate_left(Y, 8);
00181          X += Y; Y += X;
00182 
00183          RK[i] = X;
00184          RK[i+1] = rotate_left(Y, 9);
00185          }
00186       }
00187    else if(length == 32)
00188       {
00189       for(size_t i = 0; i != 256; ++i)
00190          {
00191          SB[    i] = MDS0[Q0[Q0[Q1[Q1[i]^S[ 0]]^S[ 4]]^S[ 8]]^S[12]];
00192          SB[256+i] = MDS1[Q0[Q1[Q1[Q0[i]^S[ 1]]^S[ 5]]^S[ 9]]^S[13]];
00193          SB[512+i] = MDS2[Q1[Q0[Q0[Q0[i]^S[ 2]]^S[ 6]]^S[10]]^S[14]];
00194          SB[768+i] = MDS3[Q1[Q1[Q0[Q1[i]^S[ 3]]^S[ 7]]^S[11]]^S[15]];
00195          }
00196 
00197       for(size_t i = 0; i != 40; i += 2)
00198          {
00199          u32bit X = MDS0[Q0[Q0[Q1[Q1[i  ]^key[24]]^key[16]]^key[ 8]]^key[ 0]] ^
00200                     MDS1[Q0[Q1[Q1[Q0[i  ]^key[25]]^key[17]]^key[ 9]]^key[ 1]] ^
00201                     MDS2[Q1[Q0[Q0[Q0[i  ]^key[26]]^key[18]]^key[10]]^key[ 2]] ^
00202                     MDS3[Q1[Q1[Q0[Q1[i  ]^key[27]]^key[19]]^key[11]]^key[ 3]];
00203          u32bit Y = MDS0[Q0[Q0[Q1[Q1[i+1]^key[28]]^key[20]]^key[12]]^key[ 4]] ^
00204                     MDS1[Q0[Q1[Q1[Q0[i+1]^key[29]]^key[21]]^key[13]]^key[ 5]] ^
00205                     MDS2[Q1[Q0[Q0[Q0[i+1]^key[30]]^key[22]]^key[14]]^key[ 6]] ^
00206                     MDS3[Q1[Q1[Q0[Q1[i+1]^key[31]]^key[23]]^key[15]]^key[ 7]];
00207          Y = rotate_left(Y, 8);
00208          X += Y; Y += X;
00209 
00210          RK[i] = X;
00211          RK[i+1] = rotate_left(Y, 9);
00212          }
00213       }
00214    }
00215 
00216 /*
00217 * Do one column of the RS matrix multiplcation
00218 */
00219 void Twofish::rs_mul(byte S[4], byte key, size_t offset)
00220    {
00221    if(key)
00222       {
00223       byte X = POLY_TO_EXP[key - 1];
00224 
00225       byte RS1 = RS[(4*offset  ) % 32];
00226       byte RS2 = RS[(4*offset+1) % 32];
00227       byte RS3 = RS[(4*offset+2) % 32];
00228       byte RS4 = RS[(4*offset+3) % 32];
00229 
00230       S[0] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS1 - 1]) % 255];
00231       S[1] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS2 - 1]) % 255];
00232       S[2] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS3 - 1]) % 255];
00233       S[3] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS4 - 1]) % 255];
00234       }
00235    }
00236 
00237 /*
00238 * Clear memory of sensitive data
00239 */
00240 void Twofish::clear()
00241    {
00242    zap(SB);
00243    zap(RK);
00244    }
00245 
00246 }