# HG changeset patch # User Thomas Dixon # Date 1219036477 14400 # Node ID 23c62e28b3a4b8b5465fb68093abdfb1291fc892 # Parent 23e6e80f8ee32c2259c33628bf47f86436a25a78 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. diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/BlockCipher.d --- a/dcrypt/crypto/BlockCipher.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/BlockCipher.d Mon Aug 18 01:14:37 2008 -0400 @@ -8,29 +8,12 @@ module dcrypt.crypto.BlockCipher; -public import dcrypt.crypto.Cipher; +public import dcrypt.crypto.SymmetricCipher; public import dcrypt.crypto.params.SymmetricKey; /** Interface for a standard block cipher. */ -interface BlockCipher : Cipher { +abstract class BlockCipher : SymmetricCipher { /** Returns: The block size in bytes that this cipher will operate on. */ uint blockSize(); - - /** - * Process a block of data from the input array - * and place it into the output array. - * - * Params: - * input_ = Array containing input data. - * inOff = Offset at where the data in input_ starts. - * output_ = Array which will hold the output data. - * outOff = Offset at which to begin placing data in output_. - * - * Returns: The number of bytes processed (typically blockSize). - * - * Throws: dcrypt.crypto.errors.NotInitializedError if cipher - * was not initialized. - */ - uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff); } diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/Cipher.d --- a/dcrypt/crypto/Cipher.d Sat Aug 16 22:55:38 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/** - * This file is part of the dcrypt project. - * - * Copyright: Copyright (C) dcrypt contributors 2008. All rights reserved. - * License: MIT - * Authors: Thomas Dixon - */ - -module dcrypt.crypto.Cipher; - -public import dcrypt.crypto.errors.InvalidKeyError; -public import dcrypt.crypto.errors.ShortBufferError; -public import dcrypt.crypto.errors.NotInitializedError; -public import dcrypt.crypto.errors.InvalidParameterError; - -public import dcrypt.crypto.params.CipherParameters; - -/** Base cipher class */ -interface Cipher { - static const bool ENCRYPT = true, - DECRYPT = false; - - /** - * Initialize a cipher. - * - * Params: - * encrypt = True if we are encrypting. - * params = Parameters to be passed to the cipher. (Key, rounds, etc.) - */ - void init(bool encrypt, CipherParameters params); - - /** Returns: The name of the algorithm of this cipher. */ - char[] name(); - - /** Reset cipher to its state immediately subsequent the last init. */ - void reset(); -} diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/StreamCipher.d --- a/dcrypt/crypto/StreamCipher.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/StreamCipher.d Mon Aug 18 01:14:37 2008 -0400 @@ -8,12 +8,12 @@ module dcrypt.crypto.StreamCipher; -public import dcrypt.crypto.Cipher; +public import dcrypt.crypto.SymmetricCipher; public import dcrypt.crypto.params.CipherParameters; public import dcrypt.crypto.params.SymmetricKey; /** Interface for a standard stream cipher. */ -class StreamCipher : Cipher { +abstract class StreamCipher : SymmetricCipher { /** * Process one byte of input. * @@ -22,22 +22,5 @@ * * Returns: One byte of input XORed with the keystream. */ - abstract ubyte returnByte(ubyte input); - - /** - * Process data from the input array - * and place it into the output array. - * - * Params: - * input_ = Array containing input data. - * inOff = Offset at where the data in input_ starts. - * len = Length of input_ to process. - * output_ = Array which will hold the output data. - * outOff = Offset at which to begin placing data in output_. - * - * Throws: dcrypt.crypto.errors.NotInitializedError if cipher - * was not initialized. - */ - abstract void processBytes(void[] input_, uint inOff, - uint len, void[] output_, uint outOff); + ubyte returnByte(ubyte input); } diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/SymmetricCipher.d --- a/dcrypt/crypto/SymmetricCipher.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/SymmetricCipher.d Mon Aug 18 01:14:37 2008 -0400 @@ -8,25 +8,41 @@ module dcrypt.crypto.SymmetricCipher; -import dcrypt.crypto.Cipher; -import dcrypt.crypto.params.CipherParameters; +public import dcrypt.crypto.errors.InvalidKeyError; +public import dcrypt.crypto.errors.ShortBufferError; +public import dcrypt.crypto.errors.NotInitializedError; +public import dcrypt.crypto.errors.InvalidParameterError; + +public import dcrypt.crypto.params.CipherParameters; -/** Unified cipher class for high-level API. */ -interface SymmetricCipher : Cipher { - /** - * Pass bytes through the cipher object. +/** Base symmetric cipher class */ +abstract class SymmetricCipher { + static const bool ENCRYPT = true, + DECRYPT = false; + + /** + * Initialize a cipher. * * Params: + * encrypt = True if we are encrypting. + * params = Parameters to be passed to the cipher. (Key, rounds, etc.) + */ + void init(bool encrypt, CipherParameters params); + + /** + * Process a block of plaintext data from the input array + * and return the encrypted data. + * + * Params: * input_ = Array containing input data. - * inOff = Offset at where the data in input_ starts. - * len = Length of input_ to process. - * output_ = Array which will hold the output data. - * outOff = Offset at which to begin placing data in output_. * - * Returns: The amount of bytes processed. + * Returns: The encrypted data. */ - uint update(void[] input_, uint inOff, uint len, void[] output_, uint outOff); + ubyte[] process(void[] input_); - /** Finalize and output the rest of the buffer. */ - uint finish(void[] output_, uint outOff); + /** Returns: The name of the algorithm of this cipher. */ + char[] name(); + + /** Reset cipher to its state immediately subsequent the last init. */ + void reset(); } diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/ciphers/AES.d --- a/dcrypt/crypto/ciphers/AES.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/ciphers/AES.d Mon Aug 18 01:14:37 2008 -0400 @@ -800,32 +800,29 @@ RS[cast(ubyte) t0]; } - uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff) { + ubyte[] process(void[] input_) { if (!initialized) throw new NotInitializedError(name()~": Cipher not initialized."); ubyte[] input = cast(ubyte[]) input_; - ubyte[] output = cast(ubyte[]) output_; - if ((inOff + BLOCK_SIZE) > input.length) + if (input.length < blockSize) throw new ShortBufferError(name()~": Input buffer too short"); - - if ((outOff + BLOCK_SIZE) > output.length) - throw new ShortBufferError(name()~": Output buffer too short"); - s0 = w[0] ^ Util.ubytesToUintBig(input, inOff); - s1 = w[1] ^ Util.ubytesToUintBig(input, inOff+4); - s2 = w[2] ^ Util.ubytesToUintBig(input, inOff+8); - s3 = w[3] ^ Util.ubytesToUintBig(input, inOff+12); + s0 = w[0] ^ Util.ubytesToUintBig(input, 0); + s1 = w[1] ^ Util.ubytesToUintBig(input, 4); + s2 = w[2] ^ Util.ubytesToUintBig(input, 8); + s3 = w[3] ^ Util.ubytesToUintBig(input, 12); if (encrypt) encryptBlock(); else decryptBlock(); - Util.uintToUbytesBig(s0, output, outOff); - Util.uintToUbytesBig(s1, output, outOff+4); - Util.uintToUbytesBig(s2, output, outOff+8); - Util.uintToUbytesBig(s3, output, outOff+12); + ubyte[] output = new ubyte[blockSize]; + Util.uintToUbytesBig(s0, output, 0); + Util.uintToUbytesBig(s1, output, 4); + Util.uintToUbytesBig(s2, output, 8); + Util.uintToUbytesBig(s3, output, 12); - return BLOCK_SIZE; + return output; } void reset() {} @@ -908,14 +905,14 @@ // Encryption t.init(true, key); - t.processBlock(Util.hexToUbytes(test_plaintexts[i]), 0, buffer, 0); + buffer = t.process(Util.hexToUbytes(test_plaintexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_ciphertexts[i], t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); // Decryption t.init(false, key); - t.processBlock(Util.hexToUbytes(test_ciphertexts[i]), 0, buffer, 0); + buffer = t.process(Util.hexToUbytes(test_ciphertexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_plaintexts[i], t.name~": ("~result~") != ("~test_plaintexts[i]~")"); diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/ciphers/Blowfish.d --- a/dcrypt/crypto/ciphers/Blowfish.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/ciphers/Blowfish.d Mon Aug 18 01:14:37 2008 -0400 @@ -255,21 +255,17 @@ + S3[cast(ubyte)x]); } - uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff) { + ubyte[] process(void[] input_) { if (!initialized) throw new NotInitializedError(name()~": Cipher not initialized."); ubyte[] input = cast(ubyte[]) input_; - ubyte[] output = cast(ubyte[]) output_; - if ((inOff + BLOCK_SIZE) > input.length) + if (input.length < blockSize) throw new ShortBufferError(name()~": Input buffer too short"); - - if ((outOff + BLOCK_SIZE) > output.length) - throw new ShortBufferError(name()~": Output buffer too short"); - uint xl = Util.ubytesToUintBig(input, inOff), - xr = Util.ubytesToUintBig(input, inOff+4), + uint xl = Util.ubytesToUintBig(input, 0), + xr = Util.ubytesToUintBig(input, 4), i = 0; xl ^= P[i++]; @@ -279,10 +275,11 @@ } xr ^= P[i]; - Util.uintToUbytesBig(xr, output, outOff); - Util.uintToUbytesBig(xl, output, outOff+4); + ubyte[] output = new ubyte[blockSize]; + Util.uintToUbytesBig(xr, output, 0); + Util.uintToUbytesBig(xl, output, 4); - return BLOCK_SIZE; + return output; } void reset() { @@ -304,31 +301,31 @@ ubyte[] t = new ubyte[BLOCK_SIZE]; // Initialized to 0's for (int i = 0; i < PBOX_SIZE;) { - processBlock(t, 0, t, 0); + t = process(t); P[i++] = Util.ubytesToUintBig(t, 0); P[i++] = Util.ubytesToUintBig(t, 4); } for (int i = 0; i < SBOX_SIZE;) { - processBlock(t, 0, t, 0); + t = process(t); S0[i++] = Util.ubytesToUintBig(t, 0); S0[i++] = Util.ubytesToUintBig(t, 4); } for (int i = 0; i < SBOX_SIZE;) { - processBlock(t, 0, t, 0); + t = process(t); S1[i++] = Util.ubytesToUintBig(t, 0); S1[i++] = Util.ubytesToUintBig(t, 4); } for (int i = 0; i < SBOX_SIZE;) { - processBlock(t, 0, t, 0); + t = process(t); S2[i++] = Util.ubytesToUintBig(t, 0); S2[i++] = Util.ubytesToUintBig(t, 4); } for (int i = 0; i < SBOX_SIZE;) { - processBlock(t, 0, t, 0); + t = process(t); S3[i++] = Util.ubytesToUintBig(t, 0); S3[i++] = Util.ubytesToUintBig(t, 4); } @@ -378,14 +375,14 @@ // Encryption t.init(true, key); - t.processBlock(Util.hexToUbytes(test_plaintexts[i]), 0, buffer, 0); + buffer = t.process(Util.hexToUbytes(test_plaintexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_ciphertexts[i], t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); // Decryption t.init(false, key); - t.processBlock(Util.hexToUbytes(test_ciphertexts[i]), 0, buffer, 0); + buffer = t.process(Util.hexToUbytes(test_ciphertexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_plaintexts[i], t.name~": ("~result~") != ("~test_plaintexts[i]~")"); diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/ciphers/RC4.d --- a/dcrypt/crypto/ciphers/RC4.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/ciphers/RC4.d Mon Aug 18 01:14:37 2008 -0400 @@ -49,26 +49,21 @@ return (input^state[cast(ubyte)(state[x]+state[y])]); } - void processBytes(void[] input_, uint inOff, uint len, void[] output_, uint outOff) { + ubyte[] process(void[] input_) { if (!initialized) throw new NotInitializedError(name()~": Cipher not initialized"); - ubyte[] input = cast(ubyte[]) input_; - ubyte[] output = cast(ubyte[]) output_; - - if ((inOff + len) > input.length) - throw new ShortBufferError(name()~": Input buffer too short"); + ubyte[] input = cast(ubyte[]) input_, + output = new ubyte[input.length]; - if ((outOff + len) > output.length) - throw new ShortBufferError(name()~": Output buffer too short"); - - for (int i = 0; i < len; i++) { + for (int i = 0; i < input.length; i++) { y += state[++x]; ubyte t = state[x]; state[x] = state[y]; state[y] = t; - output[outOff++] = input[inOff++] ^ state[cast(ubyte)(state[x]+state[y])]; + output[i] = input[i] ^ state[cast(ubyte)(state[x]+state[y])]; } + return output; } void reset() { @@ -187,7 +182,7 @@ r.init(true, new SymmetricKey(Util.hexToUbytes(test_key))); // Encryption - r.processBytes(Util.hexToUbytes(test_plaintexts[i]), 0, buffer.length, buffer, 0); + buffer = r.process(Util.hexToUbytes(test_plaintexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_ciphertexts[i], r.name~": ("~result~") != ("~test_ciphertexts[i]~")"); @@ -195,7 +190,7 @@ r.reset(); // Decryption - r.processBytes(Util.hexToUbytes(test_ciphertexts[i]), 0, buffer.length, buffer, 0); + buffer = r.process(Util.hexToUbytes(test_ciphertexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_plaintexts[i], r.name~": ("~result~") != ("~test_plaintexts[i]~")"); diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/ciphers/RC6.d --- a/dcrypt/crypto/ciphers/RC6.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/ciphers/RC6.d Mon Aug 18 01:14:37 2008 -0400 @@ -65,23 +65,19 @@ initialized = true; } - uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff) { + ubyte[] process(void[] input_) { if (!initialized) throw new NotInitializedError(name()~": Cipher not initialized"); ubyte[] input = cast(ubyte[]) input_; - ubyte[] output = cast(ubyte[]) output_; - if ((inOff + BLOCK_SIZE) > input.length) + if (input.length > blockSize) throw new ShortBufferError(name()~": Input buffer too short"); - - if ((outOff + BLOCK_SIZE) > output.length) - throw new ShortBufferError(name()~": Output buffer too short"); - uint A = Util.ubytesToUintLittle(input, inOff), - B = Util.ubytesToUintLittle(input, inOff+4), - C = Util.ubytesToUintLittle(input, inOff+8), - D = Util.ubytesToUintLittle(input, inOff+12), + uint A = Util.ubytesToUintLittle(input, 0), + B = Util.ubytesToUintLittle(input, 4), + C = Util.ubytesToUintLittle(input, 8), + D = Util.ubytesToUintLittle(input, 12), t, u; @@ -119,12 +115,13 @@ B -= S[0]; } - Util.uintToUbytesLittle(A, output, outOff); - Util.uintToUbytesLittle(B, output, outOff+4); - Util.uintToUbytesLittle(C, output, outOff+8); - Util.uintToUbytesLittle(D, output, outOff+12); + ubyte[] output = new ubyte[blockSize]; + Util.uintToUbytesLittle(A, output, 0); + Util.uintToUbytesLittle(B, output, 4); + Util.uintToUbytesLittle(C, output, 8); + Util.uintToUbytesLittle(D, output, 12); - return BLOCK_SIZE; + return output; } void reset() { @@ -195,14 +192,14 @@ // Encryption t.init(true, key); - t.processBlock(Util.hexToUbytes(test_plaintexts[i]), 0, buffer, 0); + buffer = t.process(Util.hexToUbytes(test_plaintexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_ciphertexts[i], t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); // Decryption t.init(false, key); - t.processBlock(Util.hexToUbytes(test_ciphertexts[i]), 0, buffer, 0); + buffer = t.process(Util.hexToUbytes(test_ciphertexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_plaintexts[i], t.name~": ("~result~") != ("~test_plaintexts[i]~")"); diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/ciphers/TEA.d --- a/dcrypt/crypto/ciphers/TEA.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/ciphers/TEA.d Mon Aug 18 01:14:37 2008 -0400 @@ -54,21 +54,17 @@ initialized = true; } - uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff) { + ubyte[] process(void[] input_) { if (!initialized) throw new NotInitializedError(name()~": Cipher not initialized"); ubyte[] input = cast(ubyte[]) input_; - ubyte[] output = cast(ubyte[]) output_; - if ((inOff + BLOCK_SIZE) > input.length) + if (input.length < blockSize) throw new ShortBufferError(name()~": Input buffer too short"); - - if ((outOff + BLOCK_SIZE) > output.length) - throw new ShortBufferError(name()~": Output buffer too short"); - uint v0 = Util.ubytesToUintBig(input, inOff), - v1 = Util.ubytesToUintBig(input, inOff+4); + uint v0 = Util.ubytesToUintBig(input, 0), + v1 = Util.ubytesToUintBig(input, 4); sum = encrypt ? 0 : DECRYPT_SUM; for (int i = 0; i < ROUNDS; i++) { @@ -83,10 +79,11 @@ } } - Util.uintToUbytesBig(v0, output, outOff); - Util.uintToUbytesBig(v1, output, outOff+4); + ubyte[] output = new ubyte[blockSize]; + Util.uintToUbytesBig(v0, output, 0); + Util.uintToUbytesBig(v1, output, 4); - return BLOCK_SIZE; + return output; } /** Some TEA test vectors. */ @@ -121,14 +118,14 @@ // Encryption t.init(true, key); - t.processBlock(Util.hexToUbytes(test_plaintexts[i]), 0, buffer, 0); + buffer = t.process(Util.hexToUbytes(test_plaintexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_ciphertexts[i], t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); // Decryption t.init(false, key); - t.processBlock(Util.hexToUbytes(test_ciphertexts[i]), 0, buffer, 0); + buffer = t.process(Util.hexToUbytes(test_ciphertexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_plaintexts[i], t.name~": ("~result~") != ("~test_plaintexts[i]~")"); diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/ciphers/XTEA.d --- a/dcrypt/crypto/ciphers/XTEA.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/ciphers/XTEA.d Mon Aug 18 01:14:37 2008 -0400 @@ -64,21 +64,17 @@ initialized = true; } - uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff) { + ubyte[] process(void[] input_) { if (!initialized) throw new NotInitializedError(name()~": Cipher not initialized"); ubyte[] input = cast(ubyte[]) input_; - ubyte[] output = cast(ubyte[]) output_; - if ((inOff + BLOCK_SIZE) > input.length) + if (input.length < blockSize) throw new ShortBufferError(name()~": Input buffer too short"); - - if ((outOff + BLOCK_SIZE) > output.length) - throw new ShortBufferError(name()~": Output buffer too short"); - uint v0 = Util.ubytesToUintBig(input, inOff), - v1 = Util.ubytesToUintBig(input, inOff+4); + uint v0 = Util.ubytesToUintBig(input, 0), + v1 = Util.ubytesToUintBig(input, 4); if (encrypt) { for (int i = 0; i < ROUNDS; i++) { @@ -92,10 +88,11 @@ } } - Util.uintToUbytesBig(v0, output, outOff); - Util.uintToUbytesBig(v1, output, outOff+4); + ubyte[] output = new ubyte[blockSize]; + Util.uintToUbytesBig(v0, output, 0); + Util.uintToUbytesBig(v1, output, 4); - return BLOCK_SIZE; + return output; } /** Some XTEA test vectors. */ @@ -148,14 +145,14 @@ // Encryption t.init(true, key); - t.processBlock(Util.hexToUbytes(test_plaintexts[i]), 0, buffer, 0); + buffer = t.process(Util.hexToUbytes(test_plaintexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_ciphertexts[i], t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); // Decryption t.init(false, key); - t.processBlock(Util.hexToUbytes(test_ciphertexts[i]), 0, buffer, 0); + buffer = t.process(Util.hexToUbytes(test_ciphertexts[i])); result = Util.ubytesToHex(buffer); assert(result == test_plaintexts[i], t.name~": ("~result~") != ("~test_plaintexts[i]~")"); diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/modes/CBC.d --- a/dcrypt/crypto/modes/CBC.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/modes/CBC.d Mon Aug 18 01:14:37 2008 -0400 @@ -67,48 +67,43 @@ initialized = true; } - uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff) { + ubyte[] process(void[] input_) { if (!initialized) throw new NotInitializedError( name()~": Block mode not initialized"); - ubyte[] input = cast(ubyte[]) input_, - output = cast(ubyte[]) output_; + ubyte[] input = cast(ubyte[]) input_; - if ((inOff + blockSize) > input.length) + if (input.length < blockSize) throw new ShortBufferError(name()~": Input buffer too short"); - - if ((outOff + blockSize) > output.length) - throw new ShortBufferError(name()~": Output buffer too short"); if (encrypt) { // P_i XOR C_i-1 for (int i = 0; i < blockSize; i++) - previousCiphertext[i] ^= input[inOff++]; + previousCiphertext[i] ^= input[i]; // E_k(P_i XOR C_i-1) - m_cipher.processBlock(previousCiphertext, 0, cbcOutput, 0); + cbcOutput[] = m_cipher.process(previousCiphertext); // Store C_i for next block - previousCiphertext[] = cbcOutput; + previousCiphertext[] = cbcOutput; - // C_i = E_k(P_i XOR C_i-1) - output[outOff..(outOff+blockSize)] = cbcOutput; } else { // Temporarily store C_i - ubyte[] t = input[inOff..(inOff+blockSize)]; + ubyte[] t = input[0..blockSize]; // D_k(C_i) - m_cipher.processBlock(t, 0, cbcOutput, 0); + cbcOutput[] = m_cipher.process(t); // P_i = D_k(C_i) XOR C_i-1 for (int i = 0; i < blockSize; i++) - output[outOff++] = (cbcOutput[i] ^ previousCiphertext[i]); + cbcOutput[i] ^= previousCiphertext[i]; // Store C_i for next block previousCiphertext[] = t; } - return blockSize; + + return cbcOutput; } uint blockSize() { @@ -163,7 +158,7 @@ // Encryption c.init(true, params); for (int j = 0; j < 32; j+=x.blockSize) - c.processBlock(Util.hexToUbytes(test_plaintexts[i]), j, buffer, j); + buffer[j..j+x.blockSize] = c.process(Util.hexToUbytes(test_plaintexts[i])[j..j+x.blockSize]); result = Util.ubytesToHex(buffer); assert(result == test_ciphertexts[i], c.name()~": ("~result~") != ("~test_ciphertexts[i]~")"); @@ -171,10 +166,10 @@ // Decryption c.init(false, params); for (int j = 0; j < 32; j+=x.blockSize) - c.processBlock(Util.hexToUbytes(test_ciphertexts[i]), j, buffer, j); + buffer[j..j+x.blockSize] = c.process(Util.hexToUbytes(test_ciphertexts[i])[j..j+x.blockSize]); result = Util.ubytesToHex(buffer); assert(result == test_plaintexts[i], - c.name()~": ("~result~") != ("~test_ciphertexts[i]~")"); + c.name()~": ("~result~") != ("~test_plaintexts[i]~")"); } } } diff -r 23e6e80f8ee3 -r 23c62e28b3a4 dcrypt/crypto/modes/CTR.d --- a/dcrypt/crypto/modes/CTR.d Sat Aug 16 22:55:38 2008 -0400 +++ b/dcrypt/crypto/modes/CTR.d Mon Aug 18 01:14:37 2008 -0400 @@ -62,26 +62,25 @@ initialized = true; } - uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff) { + ubyte[] process(void[] input_) { if (!initialized) throw new NotInitializedError( name()~": Block mode not initialized"); ubyte[] input = cast(ubyte[]) input_; - ubyte[] output = cast(ubyte[]) output_; // Encrypt the counter - m_cipher.processBlock(counter, 0, counterOutput, 0); + counterOutput[] = m_cipher.process(counter); // XOR output with plaintext to create ciphertext for (int i = 0; i < counter.length; i++) - output[outOff++] = (counterOutput[i] ^ input[inOff++]); + counterOutput[i] ^= input[i]; // Increment the counter for (int i = counter.length-1; i >= 0; i--) if (++counter[i]) break; - return counter.length; + return counterOutput; } uint blockSize() {