Mercurial > projects > dcrypt
comparison dcrypt/crypto/ciphers/Blowfish.d @ 8:23c62e28b3a4
Reworked symmetric cipher classes to have SymmetricCipher as their superclass, and follow the general interface of init(), process(), etc. Made sure everything still passed test vectors. Removed Cipher class. I'll worry about that shit when we support something other than symmetric ciphers.
author | Thomas Dixon <reikon@reikon.us> |
---|---|
date | Mon, 18 Aug 2008 01:14:37 -0400 |
parents | 5cb17e09d685 |
children | 8c7f8fecdd75 |
comparison
equal
deleted
inserted
replaced
7:23e6e80f8ee3 | 8:23c62e28b3a4 |
---|---|
253 + S1[cast(ubyte)(x >> 16)]) | 253 + S1[cast(ubyte)(x >> 16)]) |
254 ^ S2[cast(ubyte)(x >> 8)]) | 254 ^ S2[cast(ubyte)(x >> 8)]) |
255 + S3[cast(ubyte)x]); | 255 + S3[cast(ubyte)x]); |
256 } | 256 } |
257 | 257 |
258 uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff) { | 258 ubyte[] process(void[] input_) { |
259 if (!initialized) | 259 if (!initialized) |
260 throw new NotInitializedError(name()~": Cipher not initialized."); | 260 throw new NotInitializedError(name()~": Cipher not initialized."); |
261 | 261 |
262 ubyte[] input = cast(ubyte[]) input_; | 262 ubyte[] input = cast(ubyte[]) input_; |
263 ubyte[] output = cast(ubyte[]) output_; | |
264 | 263 |
265 if ((inOff + BLOCK_SIZE) > input.length) | 264 if (input.length < blockSize) |
266 throw new ShortBufferError(name()~": Input buffer too short"); | 265 throw new ShortBufferError(name()~": Input buffer too short"); |
267 | 266 |
268 if ((outOff + BLOCK_SIZE) > output.length) | 267 uint xl = Util.ubytesToUintBig(input, 0), |
269 throw new ShortBufferError(name()~": Output buffer too short"); | 268 xr = Util.ubytesToUintBig(input, 4), |
270 | |
271 uint xl = Util.ubytesToUintBig(input, inOff), | |
272 xr = Util.ubytesToUintBig(input, inOff+4), | |
273 i = 0; | 269 i = 0; |
274 | 270 |
275 xl ^= P[i++]; | 271 xl ^= P[i++]; |
276 for (; i < ROUNDS;) { | 272 for (; i < ROUNDS;) { |
277 xr ^= F(xl) ^ P[i++]; | 273 xr ^= F(xl) ^ P[i++]; |
278 xl ^= F(xr) ^ P[i++]; | 274 xl ^= F(xr) ^ P[i++]; |
279 } | 275 } |
280 xr ^= P[i]; | 276 xr ^= P[i]; |
281 | 277 |
282 Util.uintToUbytesBig(xr, output, outOff); | 278 ubyte[] output = new ubyte[blockSize]; |
283 Util.uintToUbytesBig(xl, output, outOff+4); | 279 Util.uintToUbytesBig(xr, output, 0); |
284 | 280 Util.uintToUbytesBig(xl, output, 4); |
285 return BLOCK_SIZE; | 281 |
282 return output; | |
286 } | 283 } |
287 | 284 |
288 void reset() { | 285 void reset() { |
289 setup(workingKey); | 286 setup(workingKey); |
290 } | 287 } |
302 P[i] ^= x; | 299 P[i] ^= x; |
303 } | 300 } |
304 | 301 |
305 ubyte[] t = new ubyte[BLOCK_SIZE]; // Initialized to 0's | 302 ubyte[] t = new ubyte[BLOCK_SIZE]; // Initialized to 0's |
306 for (int i = 0; i < PBOX_SIZE;) { | 303 for (int i = 0; i < PBOX_SIZE;) { |
307 processBlock(t, 0, t, 0); | 304 t = process(t); |
308 P[i++] = Util.ubytesToUintBig(t, 0); | 305 P[i++] = Util.ubytesToUintBig(t, 0); |
309 P[i++] = Util.ubytesToUintBig(t, 4); | 306 P[i++] = Util.ubytesToUintBig(t, 4); |
310 } | 307 } |
311 | 308 |
312 for (int i = 0; i < SBOX_SIZE;) { | 309 for (int i = 0; i < SBOX_SIZE;) { |
313 processBlock(t, 0, t, 0); | 310 t = process(t); |
314 S0[i++] = Util.ubytesToUintBig(t, 0); | 311 S0[i++] = Util.ubytesToUintBig(t, 0); |
315 S0[i++] = Util.ubytesToUintBig(t, 4); | 312 S0[i++] = Util.ubytesToUintBig(t, 4); |
316 } | 313 } |
317 | 314 |
318 for (int i = 0; i < SBOX_SIZE;) { | 315 for (int i = 0; i < SBOX_SIZE;) { |
319 processBlock(t, 0, t, 0); | 316 t = process(t); |
320 S1[i++] = Util.ubytesToUintBig(t, 0); | 317 S1[i++] = Util.ubytesToUintBig(t, 0); |
321 S1[i++] = Util.ubytesToUintBig(t, 4); | 318 S1[i++] = Util.ubytesToUintBig(t, 4); |
322 } | 319 } |
323 | 320 |
324 for (int i = 0; i < SBOX_SIZE;) { | 321 for (int i = 0; i < SBOX_SIZE;) { |
325 processBlock(t, 0, t, 0); | 322 t = process(t); |
326 S2[i++] = Util.ubytesToUintBig(t, 0); | 323 S2[i++] = Util.ubytesToUintBig(t, 0); |
327 S2[i++] = Util.ubytesToUintBig(t, 4); | 324 S2[i++] = Util.ubytesToUintBig(t, 4); |
328 } | 325 } |
329 | 326 |
330 for (int i = 0; i < SBOX_SIZE;) { | 327 for (int i = 0; i < SBOX_SIZE;) { |
331 processBlock(t, 0, t, 0); | 328 t = process(t); |
332 S3[i++] = Util.ubytesToUintBig(t, 0); | 329 S3[i++] = Util.ubytesToUintBig(t, 0); |
333 S3[i++] = Util.ubytesToUintBig(t, 4); | 330 S3[i++] = Util.ubytesToUintBig(t, 4); |
334 } | 331 } |
335 } | 332 } |
336 | 333 |
376 char[] result; | 373 char[] result; |
377 SymmetricKey key = new SymmetricKey(Util.hexToUbytes(test_key)); | 374 SymmetricKey key = new SymmetricKey(Util.hexToUbytes(test_key)); |
378 | 375 |
379 // Encryption | 376 // Encryption |
380 t.init(true, key); | 377 t.init(true, key); |
381 t.processBlock(Util.hexToUbytes(test_plaintexts[i]), 0, buffer, 0); | 378 buffer = t.process(Util.hexToUbytes(test_plaintexts[i])); |
382 result = Util.ubytesToHex(buffer); | 379 result = Util.ubytesToHex(buffer); |
383 assert(result == test_ciphertexts[i], | 380 assert(result == test_ciphertexts[i], |
384 t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); | 381 t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); |
385 | 382 |
386 // Decryption | 383 // Decryption |
387 t.init(false, key); | 384 t.init(false, key); |
388 t.processBlock(Util.hexToUbytes(test_ciphertexts[i]), 0, buffer, 0); | 385 buffer = t.process(Util.hexToUbytes(test_ciphertexts[i])); |
389 result = Util.ubytesToHex(buffer); | 386 result = Util.ubytesToHex(buffer); |
390 assert(result == test_plaintexts[i], | 387 assert(result == test_plaintexts[i], |
391 t.name~": ("~result~") != ("~test_plaintexts[i]~")"); | 388 t.name~": ("~result~") != ("~test_plaintexts[i]~")"); |
392 } | 389 } |
393 } | 390 } |