annotate dcrypt/crypto/modes/CTR.d @ 0:0e08791a1418

Initial import.
author Thomas Dixon <reikon@reikon.us>
date Sun, 10 Aug 2008 14:20:17 -0400
parents
children 23c62e28b3a4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
1 /**
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
2 * This file is part of the dcrypt project.
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
3 *
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
4 * Copyright: Copyright (C) dcrypt contributors 2008. All rights reserved.
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
5 * License: MIT
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
6 * Authors: Thomas Dixon
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
7 */
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
8
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
9 module dcrypt.crypto.modes.CTR;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
10
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
11 import dcrypt.crypto.BlockCipher;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
12 import dcrypt.crypto.params.ParametersWithIV;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
13
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
14
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
15 /** This class implements the counter (CTR/SIC/ICM) block mode,
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
16 treating the counter as a big endian integer. */
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
17 class CTR : BlockCipher {
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
18 private BlockCipher m_cipher;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
19 private ubyte[] iv,
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
20 counter,
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
21 counterOutput;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
22 private bool initialized = false;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
23
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
24 /**
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
25 * Params:
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
26 * cipher = Block cipher to wrap.
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
27 */
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
28 this (BlockCipher cipher) {
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
29 m_cipher = cipher;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
30 }
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
31
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
32 /** Returns: The underlying cipher we are wrapping. */
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
33 BlockCipher cipher() {
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
34 return m_cipher;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
35 }
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
36
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
37 char[] name() {
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
38 return m_cipher.name~"/CTR";
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
39 }
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
40
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
41 /**
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
42 * Throws: dcrypt.crypto.errors.InvalidParameterError if params aren't
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
43 * an instance of dcrypt.crypto.params.ParametersWithIV.
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
44 */
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
45 void init(bool encrypt, CipherParameters params) {
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
46 ParametersWithIV ivParams = cast(ParametersWithIV)params;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
47
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
48 if (!ivParams)
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
49 throw new InvalidParameterError(
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
50 name()~": Block mode requires IV (use ParametersWithIV)");
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
51 if (ivParams.iv.length != blockSize)
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
52 throw new InvalidParameterError(
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
53 name()~": IV must be same length as cipher block size");
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
54
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
55 m_cipher.init(true, ivParams.parameters);
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
56
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
57 iv = ivParams.iv[0..blockSize];
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
58 counter = new ubyte[blockSize];
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
59 counter[] = iv;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
60 counterOutput = new ubyte[blockSize];
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
61
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
62 initialized = true;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
63 }
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
64
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
65 uint processBlock(void[] input_, uint inOff, void[] output_, uint outOff) {
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
66 if (!initialized)
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
67 throw new NotInitializedError(
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
68 name()~": Block mode not initialized");
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
69
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
70 ubyte[] input = cast(ubyte[]) input_;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
71 ubyte[] output = cast(ubyte[]) output_;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
72
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
73 // Encrypt the counter
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
74 m_cipher.processBlock(counter, 0, counterOutput, 0);
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
75
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
76 // XOR output with plaintext to create ciphertext
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
77 for (int i = 0; i < counter.length; i++)
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
78 output[outOff++] = (counterOutput[i] ^ input[inOff++]);
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
79
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
80 // Increment the counter
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
81 for (int i = counter.length-1; i >= 0; i--)
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
82 if (++counter[i]) break;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
83
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
84 return counter.length;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
85 }
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
86
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
87 uint blockSize() {
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
88 return m_cipher.blockSize;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
89 }
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
90
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
91 void reset() {
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
92 counter[] = iv;
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
93 m_cipher.reset();
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
94 }
0e08791a1418 Initial import.
Thomas Dixon <reikon@reikon.us>
parents:
diff changeset
95 }