Mercurial > projects > dcrypt
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 } |