Botan  1.10.9
twofish.cpp
Go to the documentation of this file.
1 /*
2 * Twofish
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * The key schedule implemenation is based on a public domain
6 * implementation by Matthew Skala
7 *
8 * Distributed under the terms of the Botan license
9 */
10 
11 #include <botan/twofish.h>
12 #include <botan/loadstor.h>
13 #include <botan/rotate.h>
14 
15 namespace Botan {
16 
17 /*
18 * Twofish Encryption
19 */
20 void Twofish::encrypt_n(const byte in[], byte out[], size_t blocks) const
21  {
22  for(size_t i = 0; i != blocks; ++i)
23  {
24  u32bit A = load_le<u32bit>(in, 0) ^ RK[0];
25  u32bit B = load_le<u32bit>(in, 1) ^ RK[1];
26  u32bit C = load_le<u32bit>(in, 2) ^ RK[2];
27  u32bit D = load_le<u32bit>(in, 3) ^ RK[3];
28 
29  for(size_t j = 0; j != 16; j += 2)
30  {
31  u32bit X, Y;
32 
33  X = SB[ get_byte(3, A)] ^ SB[256+get_byte(2, A)] ^
34  SB[512+get_byte(1, A)] ^ SB[768+get_byte(0, A)];
35  Y = SB[ get_byte(0, B)] ^ SB[256+get_byte(3, B)] ^
36  SB[512+get_byte(2, B)] ^ SB[768+get_byte(1, B)];
37  X += Y;
38  Y += X + RK[2*j + 9];
39  X += RK[2*j + 8];
40 
41  C = rotate_right(C ^ X, 1);
42  D = rotate_left(D, 1) ^ Y;
43 
44  X = SB[ get_byte(3, C)] ^ SB[256+get_byte(2, C)] ^
45  SB[512+get_byte(1, C)] ^ SB[768+get_byte(0, C)];
46  Y = SB[ get_byte(0, D)] ^ SB[256+get_byte(3, D)] ^
47  SB[512+get_byte(2, D)] ^ SB[768+get_byte(1, D)];
48  X += Y;
49  Y += X + RK[2*j + 11];
50  X += RK[2*j + 10];
51 
52  A = rotate_right(A ^ X, 1);
53  B = rotate_left(B, 1) ^ Y;
54  }
55 
56  C ^= RK[4];
57  D ^= RK[5];
58  A ^= RK[6];
59  B ^= RK[7];
60 
61  store_le(out, C, D, A, B);
62 
63  in += BLOCK_SIZE;
64  out += BLOCK_SIZE;
65  }
66  }
67 
68 /*
69 * Twofish Decryption
70 */
71 void Twofish::decrypt_n(const byte in[], byte out[], size_t blocks) const
72  {
73  for(size_t i = 0; i != blocks; ++i)
74  {
75  u32bit A = load_le<u32bit>(in, 0) ^ RK[4];
76  u32bit B = load_le<u32bit>(in, 1) ^ RK[5];
77  u32bit C = load_le<u32bit>(in, 2) ^ RK[6];
78  u32bit D = load_le<u32bit>(in, 3) ^ RK[7];
79 
80  for(size_t j = 0; j != 16; j += 2)
81  {
82  u32bit X, Y;
83 
84  X = SB[ get_byte(3, A)] ^ SB[256+get_byte(2, A)] ^
85  SB[512+get_byte(1, A)] ^ SB[768+get_byte(0, A)];
86  Y = SB[ get_byte(0, B)] ^ SB[256+get_byte(3, B)] ^
87  SB[512+get_byte(2, B)] ^ SB[768+get_byte(1, B)];
88  X += Y;
89  Y += X + RK[39 - 2*j];
90  X += RK[38 - 2*j];
91 
92  C = rotate_left(C, 1) ^ X;
93  D = rotate_right(D ^ Y, 1);
94 
95  X = SB[ get_byte(3, C)] ^ SB[256+get_byte(2, C)] ^
96  SB[512+get_byte(1, C)] ^ SB[768+get_byte(0, C)];
97  Y = SB[ get_byte(0, D)] ^ SB[256+get_byte(3, D)] ^
98  SB[512+get_byte(2, D)] ^ SB[768+get_byte(1, D)];
99  X += Y;
100  Y += X + RK[37 - 2*j];
101  X += RK[36 - 2*j];
102 
103  A = rotate_left(A, 1) ^ X;
104  B = rotate_right(B ^ Y, 1);
105  }
106 
107  C ^= RK[0];
108  D ^= RK[1];
109  A ^= RK[2];
110  B ^= RK[3];
111 
112  store_le(out, C, D, A, B);
113 
114  in += BLOCK_SIZE;
115  out += BLOCK_SIZE;
116  }
117  }
118 
119 /*
120 * Twofish Key Schedule
121 */
122 void Twofish::key_schedule(const byte key[], size_t length)
123  {
124  SecureVector<byte> S(16);
125 
126  for(size_t i = 0; i != length; ++i)
127  rs_mul(&S[4*(i/8)], key[i], i);
128 
129  if(length == 16)
130  {
131  for(size_t i = 0; i != 256; ++i)
132  {
133  SB[ i] = MDS0[Q0[Q0[i]^S[ 0]]^S[ 4]];
134  SB[256+i] = MDS1[Q0[Q1[i]^S[ 1]]^S[ 5]];
135  SB[512+i] = MDS2[Q1[Q0[i]^S[ 2]]^S[ 6]];
136  SB[768+i] = MDS3[Q1[Q1[i]^S[ 3]]^S[ 7]];
137  }
138 
139  for(size_t i = 0; i != 40; i += 2)
140  {
141  u32bit X = MDS0[Q0[Q0[i ]^key[ 8]]^key[ 0]] ^
142  MDS1[Q0[Q1[i ]^key[ 9]]^key[ 1]] ^
143  MDS2[Q1[Q0[i ]^key[10]]^key[ 2]] ^
144  MDS3[Q1[Q1[i ]^key[11]]^key[ 3]];
145  u32bit Y = MDS0[Q0[Q0[i+1]^key[12]]^key[ 4]] ^
146  MDS1[Q0[Q1[i+1]^key[13]]^key[ 5]] ^
147  MDS2[Q1[Q0[i+1]^key[14]]^key[ 6]] ^
148  MDS3[Q1[Q1[i+1]^key[15]]^key[ 7]];
149  Y = rotate_left(Y, 8);
150  X += Y; Y += X;
151 
152  RK[i] = X;
153  RK[i+1] = rotate_left(Y, 9);
154  }
155  }
156  else if(length == 24)
157  {
158  for(size_t i = 0; i != 256; ++i)
159  {
160  SB[ i] = MDS0[Q0[Q0[Q1[i]^S[ 0]]^S[ 4]]^S[ 8]];
161  SB[256+i] = MDS1[Q0[Q1[Q1[i]^S[ 1]]^S[ 5]]^S[ 9]];
162  SB[512+i] = MDS2[Q1[Q0[Q0[i]^S[ 2]]^S[ 6]]^S[10]];
163  SB[768+i] = MDS3[Q1[Q1[Q0[i]^S[ 3]]^S[ 7]]^S[11]];
164  }
165 
166  for(size_t i = 0; i != 40; i += 2)
167  {
168  u32bit X = MDS0[Q0[Q0[Q1[i ]^key[16]]^key[ 8]]^key[ 0]] ^
169  MDS1[Q0[Q1[Q1[i ]^key[17]]^key[ 9]]^key[ 1]] ^
170  MDS2[Q1[Q0[Q0[i ]^key[18]]^key[10]]^key[ 2]] ^
171  MDS3[Q1[Q1[Q0[i ]^key[19]]^key[11]]^key[ 3]];
172  u32bit Y = MDS0[Q0[Q0[Q1[i+1]^key[20]]^key[12]]^key[ 4]] ^
173  MDS1[Q0[Q1[Q1[i+1]^key[21]]^key[13]]^key[ 5]] ^
174  MDS2[Q1[Q0[Q0[i+1]^key[22]]^key[14]]^key[ 6]] ^
175  MDS3[Q1[Q1[Q0[i+1]^key[23]]^key[15]]^key[ 7]];
176  Y = rotate_left(Y, 8);
177  X += Y; Y += X;
178 
179  RK[i] = X;
180  RK[i+1] = rotate_left(Y, 9);
181  }
182  }
183  else if(length == 32)
184  {
185  for(size_t i = 0; i != 256; ++i)
186  {
187  SB[ i] = MDS0[Q0[Q0[Q1[Q1[i]^S[ 0]]^S[ 4]]^S[ 8]]^S[12]];
188  SB[256+i] = MDS1[Q0[Q1[Q1[Q0[i]^S[ 1]]^S[ 5]]^S[ 9]]^S[13]];
189  SB[512+i] = MDS2[Q1[Q0[Q0[Q0[i]^S[ 2]]^S[ 6]]^S[10]]^S[14]];
190  SB[768+i] = MDS3[Q1[Q1[Q0[Q1[i]^S[ 3]]^S[ 7]]^S[11]]^S[15]];
191  }
192 
193  for(size_t i = 0; i != 40; i += 2)
194  {
195  u32bit X = MDS0[Q0[Q0[Q1[Q1[i ]^key[24]]^key[16]]^key[ 8]]^key[ 0]] ^
196  MDS1[Q0[Q1[Q1[Q0[i ]^key[25]]^key[17]]^key[ 9]]^key[ 1]] ^
197  MDS2[Q1[Q0[Q0[Q0[i ]^key[26]]^key[18]]^key[10]]^key[ 2]] ^
198  MDS3[Q1[Q1[Q0[Q1[i ]^key[27]]^key[19]]^key[11]]^key[ 3]];
199  u32bit Y = MDS0[Q0[Q0[Q1[Q1[i+1]^key[28]]^key[20]]^key[12]]^key[ 4]] ^
200  MDS1[Q0[Q1[Q1[Q0[i+1]^key[29]]^key[21]]^key[13]]^key[ 5]] ^
201  MDS2[Q1[Q0[Q0[Q0[i+1]^key[30]]^key[22]]^key[14]]^key[ 6]] ^
202  MDS3[Q1[Q1[Q0[Q1[i+1]^key[31]]^key[23]]^key[15]]^key[ 7]];
203  Y = rotate_left(Y, 8);
204  X += Y; Y += X;
205 
206  RK[i] = X;
207  RK[i+1] = rotate_left(Y, 9);
208  }
209  }
210  }
211 
212 /*
213 * Do one column of the RS matrix multiplcation
214 */
215 void Twofish::rs_mul(byte S[4], byte key, size_t offset)
216  {
217  if(key)
218  {
219  byte X = POLY_TO_EXP[key - 1];
220 
221  byte RS1 = RS[(4*offset ) % 32];
222  byte RS2 = RS[(4*offset+1) % 32];
223  byte RS3 = RS[(4*offset+2) % 32];
224  byte RS4 = RS[(4*offset+3) % 32];
225 
226  S[0] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS1 - 1]) % 255];
227  S[1] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS2 - 1]) % 255];
228  S[2] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS3 - 1]) % 255];
229  S[3] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS4 - 1]) % 255];
230  }
231  }
232 
233 /*
234 * Clear memory of sensitive data
235 */
237  {
238  zeroise(SB);
239  zeroise(RK);
240  }
241 
242 }
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: twofish.cpp:20
void decrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: twofish.cpp:71
void store_le(u16bit in, byte out[2])
Definition: loadstor.h:427
T rotate_left(T input, size_t rot)
Definition: rotate.h:21
byte get_byte(size_t byte_num, T input)
Definition: get_byte.h:21
unsigned char byte
Definition: types.h:22
T rotate_right(T input, size_t rot)
Definition: rotate.h:34
u32bit load_le< u32bit >(const byte in[], size_t off)
Definition: loadstor.h:183
void clear()
Definition: twofish.cpp:236
void zeroise(MemoryRegion< T > &vec)
Definition: secmem.h:415
unsigned int u32bit
Definition: types.h:32