comparison dcrypt/crypto/ciphers/Blowfish.d @ 20:3a57367afe34

Fixed bug which prevented Blowfish from resetting correctly.
author Thomas Dixon <reikon@reikon.us>
date Fri, 09 Jan 2009 01:24:45 -0500
parents 5ce3012f1def
children ec23779ee794
comparison
equal deleted inserted replaced
19:6e11990d031d 20:3a57367afe34
229 uint len = keyParams.key.length; 229 uint len = keyParams.key.length;
230 if (len < MIN_KEY_SIZE || len > MAX_KEY_SIZE) 230 if (len < MIN_KEY_SIZE || len > MAX_KEY_SIZE)
231 throw new InvalidKeyError( 231 throw new InvalidKeyError(
232 name()~": Invalid key length (requires 4-56 bytes)"); 232 name()~": Invalid key length (requires 4-56 bytes)");
233 233
234 workingKey = keyParams.key;
235
236 // Yes, this is ghetto. I know.
237 _initialized = true;
238
239 setup(workingKey);
240
241 if (!_encrypt)
242 P.reverse; // Oh yes I did.
243 }
244
245 private uint F(uint x) {
246 return (((S0[(x >> 24)]
247 + S1[cast(ubyte)(x >> 16)])
248 ^ S2[cast(ubyte)(x >> 8)])
249 + S3[cast(ubyte)x]);
250 }
251
252 uint update(void[] input_, void[] output_) {
253 if (!_initialized)
254 throw new NotInitializedError(name()~": Cipher not initialized.");
255
256 ubyte[] input = cast(ubyte[]) input_,
257 output = cast(ubyte[]) output_;
258
259 if (input.length < BLOCK_SIZE)
260 throw new ShortBufferError(name()~": Input buffer too short");
261
262 if (output.length < BLOCK_SIZE)
263 throw new ShortBufferError(name()~": Output buffer too short");
264
265 uint xl = Util.ubytesToUintBig(input, 0),
266 xr = Util.ubytesToUintBig(input, 4),
267 i = 0;
268
269 xl ^= P[i++];
270 for (; i < ROUNDS;) {
271 xr ^= F(xl) ^ P[i++];
272 xl ^= F(xr) ^ P[i++];
273 }
274 xr ^= P[i];
275
276 Util.uintToUbytesBig(xr, output, 0);
277 Util.uintToUbytesBig(xl, output, 4);
278
279 return BLOCK_SIZE;
280 }
281
282 void reset() {
283 setup(workingKey);
284 }
285
286 private void setup(ubyte[] key) {
234 S0[] = S_INIT[0..256]; 287 S0[] = S_INIT[0..256];
235 S1[] = S_INIT[256..512]; 288 S1[] = S_INIT[256..512];
236 S2[] = S_INIT[512..768]; 289 S2[] = S_INIT[512..768];
237 S3[] = S_INIT[768..1024]; 290 S3[] = S_INIT[768..1024];
238 P[] = P_INIT[]; 291 P[] = P_INIT[];
239 292
240 workingKey = keyParams.key;
241 // Yes, this is ghetto. I know.
242 _initialized = true;
243 setup(workingKey);
244
245 if (!_encrypt)
246 P.reverse; // Oh yes I did.
247 }
248
249 private uint F(uint x) {
250 return (((S0[(x >> 24)]
251 + S1[cast(ubyte)(x >> 16)])
252 ^ S2[cast(ubyte)(x >> 8)])
253 + S3[cast(ubyte)x]);
254 }
255
256 uint update(void[] input_, void[] output_) {
257 if (!_initialized)
258 throw new NotInitializedError(name()~": Cipher not initialized.");
259
260 ubyte[] input = cast(ubyte[]) input_,
261 output = cast(ubyte[]) output_;
262
263 if (input.length < BLOCK_SIZE)
264 throw new ShortBufferError(name()~": Input buffer too short");
265
266 if (output.length < BLOCK_SIZE)
267 throw new ShortBufferError(name()~": Output buffer too short");
268
269 uint xl = Util.ubytesToUintBig(input, 0),
270 xr = Util.ubytesToUintBig(input, 4),
271 i = 0;
272
273 xl ^= P[i++];
274 for (; i < ROUNDS;) {
275 xr ^= F(xl) ^ P[i++];
276 xl ^= F(xr) ^ P[i++];
277 }
278 xr ^= P[i];
279
280 Util.uintToUbytesBig(xr, output, 0);
281 Util.uintToUbytesBig(xl, output, 4);
282
283 return BLOCK_SIZE;
284 }
285
286 void reset() {
287 setup(workingKey);
288 }
289
290 private void setup(ubyte[] key) {
291 uint index = 0; 293 uint index = 0;
292 294
293 for (int i = 0; i < PBOX_SIZE; i++) { 295 for (int i = 0; i < PBOX_SIZE; i++) {
294 uint x = 0; 296 uint x = 0;
295 for (int j = 0; j < 4; j++) { 297 for (int j = 0; j < 4; j++) {