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