Botan
1.11.15
|
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 }