Botan 1.10.17
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
15namespace Botan {
16
17/*
18* Twofish Encryption
19*/
20void 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*/
71void 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*/
122void 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*/
215void 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 decrypt_n(const byte in[], byte out[], size_t blocks) const
Definition twofish.cpp:71
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition twofish.cpp:20
void zeroise(MemoryRegion< T > &vec)
Definition secmem.h:428
byte get_byte(size_t byte_num, T input)
Definition get_byte.h:21
T rotate_right(T input, size_t rot)
Definition rotate.h:34
T rotate_left(T input, size_t rot)
Definition rotate.h:21
T load_le(const byte in[], size_t off)
Definition loadstor.h:116
unsigned int u32bit
Definition types.h:32
void store_le(u16bit in, byte out[2])
Definition loadstor.h:427