comparison dcrypt/crypto/ciphers/Blowfish.d @ 23:4589f8c5eb3c

Replaced dcrypt.crypto.Util with dcrypt.misc.Bitwise and dcrypt.misc.ByteConverter. Altered all dependent files to reflect changes.
author Thomas Dixon <reikon@reikon.us>
date Sat, 14 Feb 2009 19:58:20 -0500
parents ec23779ee794
children 176c933827a8
comparison
equal deleted inserted replaced
22:74303a717032 23:4589f8c5eb3c
8 * Authors: Thomas Dixon 8 * Authors: Thomas Dixon
9 */ 9 */
10 10
11 module dcrypt.crypto.ciphers.Blowfish; 11 module dcrypt.crypto.ciphers.Blowfish;
12 12
13 import dcrypt.misc.Util; 13 import dcrypt.misc.ByteConverter;
14 import dcrypt.misc.Bitwise;
14 import dcrypt.crypto.BlockCipher; 15 import dcrypt.crypto.BlockCipher;
15 16
16 /** Implementation of the Blowfish cipher designed by Bruce Schneier. */ 17 /** Implementation of the Blowfish cipher designed by Bruce Schneier. */
17 class Blowfish : BlockCipher { 18 class Blowfish : BlockCipher {
18 private { 19 private {
260 throw new ShortBufferError(name()~": Input buffer too short"); 261 throw new ShortBufferError(name()~": Input buffer too short");
261 262
262 if (output.length < BLOCK_SIZE) 263 if (output.length < BLOCK_SIZE)
263 throw new ShortBufferError(name()~": Output buffer too short"); 264 throw new ShortBufferError(name()~": Output buffer too short");
264 265
265 uint xl = Util.ubytesToUintBig(input, 0), 266 uint xl = ByteConverter.BigEndian.to!(uint)(input[0..4]),
266 xr = Util.ubytesToUintBig(input, 4), 267 xr = ByteConverter.BigEndian.to!(uint)(input[4..8]),
267 i = 0; 268 i = 0;
268 269
269 xl ^= P[i++]; 270 xl ^= P[i++];
270 for (; i < ROUNDS;) { 271 for (; i < ROUNDS;) {
271 xr ^= F(xl) ^ P[i++]; 272 xr ^= F(xl) ^ P[i++];
272 xl ^= F(xr) ^ P[i++]; 273 xl ^= F(xr) ^ P[i++];
273 } 274 }
274 xr ^= P[i]; 275 xr ^= P[i];
275 276
276 Util.uintToUbytesBig(xr, output, 0); 277 output[0..4] = ByteConverter.BigEndian.from!(uint)(xr);
277 Util.uintToUbytesBig(xl, output, 4); 278 output[4..8] = ByteConverter.BigEndian.from!(uint)(xl);
278 279
279 return BLOCK_SIZE; 280 return BLOCK_SIZE;
280 } 281 }
281 282
282 void reset() { 283 void reset() {
303 } 304 }
304 305
305 ubyte[] t = new ubyte[BLOCK_SIZE]; // Initialized to 0's 306 ubyte[] t = new ubyte[BLOCK_SIZE]; // Initialized to 0's
306 for (int i = 0; i < PBOX_SIZE;) { 307 for (int i = 0; i < PBOX_SIZE;) {
307 update(t, t); 308 update(t, t);
308 P[i++] = Util.ubytesToUintBig(t, 0); 309 P[i++] = ByteConverter.BigEndian.to!(uint)(t[0..4]);
309 P[i++] = Util.ubytesToUintBig(t, 4); 310 P[i++] = ByteConverter.BigEndian.to!(uint)(t[4..8]);
310 } 311 }
311 312
312 for (int i = 0; i < SBOX_SIZE;) { 313 for (int i = 0; i < SBOX_SIZE;) {
313 update(t, t); 314 update(t, t);
314 S0[i++] = Util.ubytesToUintBig(t, 0); 315 S0[i++] = ByteConverter.BigEndian.to!(uint)(t[0..4]);
315 S0[i++] = Util.ubytesToUintBig(t, 4); 316 S0[i++] = ByteConverter.BigEndian.to!(uint)(t[4..8]);
316 } 317 }
317 318
318 for (int i = 0; i < SBOX_SIZE;) { 319 for (int i = 0; i < SBOX_SIZE;) {
319 update(t, t); 320 update(t, t);
320 S1[i++] = Util.ubytesToUintBig(t, 0); 321 S1[i++] = ByteConverter.BigEndian.to!(uint)(t[0..4]);
321 S1[i++] = Util.ubytesToUintBig(t, 4); 322 S1[i++] = ByteConverter.BigEndian.to!(uint)(t[4..8]);
322 } 323 }
323 324
324 for (int i = 0; i < SBOX_SIZE;) { 325 for (int i = 0; i < SBOX_SIZE;) {
325 update(t, t); 326 update(t, t);
326 S2[i++] = Util.ubytesToUintBig(t, 0); 327 S2[i++] = ByteConverter.BigEndian.to!(uint)(t[0..4]);
327 S2[i++] = Util.ubytesToUintBig(t, 4); 328 S2[i++] = ByteConverter.BigEndian.to!(uint)(t[4..8]);
328 } 329 }
329 330
330 for (int i = 0; i < SBOX_SIZE;) { 331 for (int i = 0; i < SBOX_SIZE;) {
331 update(t, t); 332 update(t, t);
332 S3[i++] = Util.ubytesToUintBig(t, 0); 333 S3[i++] = ByteConverter.BigEndian.to!(uint)(t[0..4]);
333 S3[i++] = Util.ubytesToUintBig(t, 4); 334 S3[i++] = ByteConverter.BigEndian.to!(uint)(t[4..8]);
334 } 335 }
335 } 336 }
336 337
337 /** Some Blowfish test vectors from Schneier's site. */ 338 /** Some Blowfish test vectors from Schneier's site. */
338 version (UnitTest) { 339 version (UnitTest) {
369 370
370 Blowfish t = new Blowfish(); 371 Blowfish t = new Blowfish();
371 foreach (uint i, char[] test_key; test_keys) { 372 foreach (uint i, char[] test_key; test_keys) {
372 ubyte[] buffer = new ubyte[t.blockSize]; 373 ubyte[] buffer = new ubyte[t.blockSize];
373 char[] result; 374 char[] result;
374 SymmetricKey key = new SymmetricKey(Util.hexToUbytes(test_key)); 375 SymmetricKey key = new SymmetricKey(ByteConverter.hexDecode(test_key));
375 376
376 // Encryption 377 // Encryption
377 t.init(true, key); 378 t.init(true, key);
378 t.update(Util.hexToUbytes(test_plaintexts[i]), buffer); 379 t.update(ByteConverter.hexDecode(test_plaintexts[i]), buffer);
379 result = Util.ubytesToHex(buffer); 380 result = ByteConverter.hexEncode(buffer);
380 assert(result == test_ciphertexts[i], 381 assert(result == test_ciphertexts[i],
381 t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); 382 t.name~": ("~result~") != ("~test_ciphertexts[i]~")");
382 383
383 // Decryption 384 // Decryption
384 t.init(false, key); 385 t.init(false, key);
385 t.update(Util.hexToUbytes(test_ciphertexts[i]), buffer); 386 t.update(ByteConverter.hexDecode(test_ciphertexts[i]), buffer);
386 result = Util.ubytesToHex(buffer); 387 result = ByteConverter.hexEncode(buffer);
387 assert(result == test_plaintexts[i], 388 assert(result == test_plaintexts[i],
388 t.name~": ("~result~") != ("~test_plaintexts[i]~")"); 389 t.name~": ("~result~") != ("~test_plaintexts[i]~")");
389 } 390 }
390 } 391 }
391 } 392 }