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