comparison dcrypt/crypto/modes/CBC.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 0e08791a1418
children 8c7f8fecdd75
comparison
equal deleted inserted replaced
7:23e6e80f8ee3 8:23c62e28b3a4
65 cbcOutput = new ubyte[blockSize]; // Output buffer for E_k/D_k(...) 65 cbcOutput = new ubyte[blockSize]; // Output buffer for E_k/D_k(...)
66 66
67 initialized = true; 67 initialized = true;
68 } 68 }
69 69
70 uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff) { 70 ubyte[] process(void[] input_) {
71 if (!initialized) 71 if (!initialized)
72 throw new NotInitializedError( 72 throw new NotInitializedError(
73 name()~": Block mode not initialized"); 73 name()~": Block mode not initialized");
74 74
75 ubyte[] input = cast(ubyte[]) input_, 75 ubyte[] input = cast(ubyte[]) input_;
76 output = cast(ubyte[]) output_;
77 76
78 if ((inOff + blockSize) > input.length) 77 if (input.length < blockSize)
79 throw new ShortBufferError(name()~": Input buffer too short"); 78 throw new ShortBufferError(name()~": Input buffer too short");
80
81 if ((outOff + blockSize) > output.length)
82 throw new ShortBufferError(name()~": Output buffer too short");
83 79
84 if (encrypt) { 80 if (encrypt) {
85 // P_i XOR C_i-1 81 // P_i XOR C_i-1
86 for (int i = 0; i < blockSize; i++) 82 for (int i = 0; i < blockSize; i++)
87 previousCiphertext[i] ^= input[inOff++]; 83 previousCiphertext[i] ^= input[i];
88 84
89 // E_k(P_i XOR C_i-1) 85 // E_k(P_i XOR C_i-1)
90 m_cipher.processBlock(previousCiphertext, 0, cbcOutput, 0); 86 cbcOutput[] = m_cipher.process(previousCiphertext);
91 87
92 // Store C_i for next block 88 // Store C_i for next block
93 previousCiphertext[] = cbcOutput; 89 previousCiphertext[] = cbcOutput;
94 90
95 // C_i = E_k(P_i XOR C_i-1)
96 output[outOff..(outOff+blockSize)] = cbcOutput;
97 } else { 91 } else {
98 // Temporarily store C_i 92 // Temporarily store C_i
99 ubyte[] t = input[inOff..(inOff+blockSize)]; 93 ubyte[] t = input[0..blockSize];
100 94
101 // D_k(C_i) 95 // D_k(C_i)
102 m_cipher.processBlock(t, 0, cbcOutput, 0); 96 cbcOutput[] = m_cipher.process(t);
103 97
104 // P_i = D_k(C_i) XOR C_i-1 98 // P_i = D_k(C_i) XOR C_i-1
105 for (int i = 0; i < blockSize; i++) 99 for (int i = 0; i < blockSize; i++)
106 output[outOff++] = (cbcOutput[i] ^ previousCiphertext[i]); 100 cbcOutput[i] ^= previousCiphertext[i];
107 101
108 // Store C_i for next block 102 // Store C_i for next block
109 previousCiphertext[] = t; 103 previousCiphertext[] = t;
110 } 104 }
111 return blockSize; 105
106 return cbcOutput;
112 } 107 }
113 108
114 uint blockSize() { 109 uint blockSize() {
115 return m_cipher.blockSize; 110 return m_cipher.blockSize;
116 } 111 }
161 ParametersWithIV params = new ParametersWithIV(key, iv); 156 ParametersWithIV params = new ParametersWithIV(key, iv);
162 157
163 // Encryption 158 // Encryption
164 c.init(true, params); 159 c.init(true, params);
165 for (int j = 0; j < 32; j+=x.blockSize) 160 for (int j = 0; j < 32; j+=x.blockSize)
166 c.processBlock(Util.hexToUbytes(test_plaintexts[i]), j, buffer, j); 161 buffer[j..j+x.blockSize] = c.process(Util.hexToUbytes(test_plaintexts[i])[j..j+x.blockSize]);
167 result = Util.ubytesToHex(buffer); 162 result = Util.ubytesToHex(buffer);
168 assert(result == test_ciphertexts[i], 163 assert(result == test_ciphertexts[i],
169 c.name()~": ("~result~") != ("~test_ciphertexts[i]~")"); 164 c.name()~": ("~result~") != ("~test_ciphertexts[i]~")");
170 165
171 // Decryption 166 // Decryption
172 c.init(false, params); 167 c.init(false, params);
173 for (int j = 0; j < 32; j+=x.blockSize) 168 for (int j = 0; j < 32; j+=x.blockSize)
174 c.processBlock(Util.hexToUbytes(test_ciphertexts[i]), j, buffer, j); 169 buffer[j..j+x.blockSize] = c.process(Util.hexToUbytes(test_ciphertexts[i])[j..j+x.blockSize]);
175 result = Util.ubytesToHex(buffer); 170 result = Util.ubytesToHex(buffer);
176 assert(result == test_plaintexts[i], 171 assert(result == test_plaintexts[i],
177 c.name()~": ("~result~") != ("~test_ciphertexts[i]~")"); 172 c.name()~": ("~result~") != ("~test_plaintexts[i]~")");
178 } 173 }
179 } 174 }
180 } 175 }
181 } 176 }