Mercurial > projects > dcrypt
annotate dcrypt/crypto/ciphers/RC4.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 |
rev | line source |
---|---|
0 | 1 /** |
2 * This file is part of the dcrypt project. | |
3 * | |
4 * Copyright: Copyright (C) dcrypt contributors 2008. All rights reserved. | |
5 * License: MIT | |
6 * Authors: Thomas Dixon | |
7 */ | |
8 | |
9 module dcrypt.crypto.ciphers.RC4; | |
10 | |
11 import dcrypt.crypto.StreamCipher; | |
12 | |
13 version (UnitTest) { | |
14 import dcrypt.misc.Util; | |
15 } | |
16 | |
17 /** Implementation of RC4 designed by Ron Rivest of RSA Security. */ | |
18 class RC4 : StreamCipher { | |
1
483e4467b5f6
Added Blowfish with test vectors. Minor cleanup of other cipher classes (should probably clean more). Continued work on high-level cipher API (didn't get very far).
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
19 private { |
483e4467b5f6
Added Blowfish with test vectors. Minor cleanup of other cipher classes (should probably clean more). Continued work on high-level cipher API (didn't get very far).
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
20 ubyte[] state, |
483e4467b5f6
Added Blowfish with test vectors. Minor cleanup of other cipher classes (should probably clean more). Continued work on high-level cipher API (didn't get very far).
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
21 workingKey; |
483e4467b5f6
Added Blowfish with test vectors. Minor cleanup of other cipher classes (should probably clean more). Continued work on high-level cipher API (didn't get very far).
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
22 ubyte x, y; |
483e4467b5f6
Added Blowfish with test vectors. Minor cleanup of other cipher classes (should probably clean more). Continued work on high-level cipher API (didn't get very far).
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
23 bool initialized; |
483e4467b5f6
Added Blowfish with test vectors. Minor cleanup of other cipher classes (should probably clean more). Continued work on high-level cipher API (didn't get very far).
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
24 } |
0 | 25 |
26 void init(bool encrypt, CipherParameters params) { | |
27 SymmetricKey keyParams = cast(SymmetricKey)params; | |
28 if (!keyParams) | |
29 throw new InvalidParameterError( | |
30 name()~": Invalid parameter passed to init"); | |
31 if (keyParams.key.length < 0 || keyParams.key.length > 256) | |
32 throw new InvalidKeyError( | |
33 name()~": Invalid key length (requires 1-256 bytes)"); | |
34 workingKey = keyParams.key; | |
35 state = new ubyte[256]; | |
36 setup(workingKey); | |
37 initialized = true; | |
38 } | |
39 | |
40 char[] name() { | |
41 return "RC4"; | |
42 } | |
43 | |
44 ubyte returnByte(ubyte input) { | |
45 y += state[++x]; | |
46 ubyte t = state[x]; | |
47 state[x] = state[y]; | |
48 state[y] = t; | |
49 return (input^state[cast(ubyte)(state[x]+state[y])]); | |
50 } | |
51 | |
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.
Thomas Dixon <reikon@reikon.us>
parents:
6
diff
changeset
|
52 ubyte[] process(void[] input_) { |
0 | 53 if (!initialized) |
54 throw new NotInitializedError(name()~": Cipher not initialized"); | |
55 | |
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.
Thomas Dixon <reikon@reikon.us>
parents:
6
diff
changeset
|
56 ubyte[] input = cast(ubyte[]) input_, |
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.
Thomas Dixon <reikon@reikon.us>
parents:
6
diff
changeset
|
57 output = new ubyte[input.length]; |
0 | 58 |
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.
Thomas Dixon <reikon@reikon.us>
parents:
6
diff
changeset
|
59 for (int i = 0; i < input.length; i++) { |
0 | 60 y += state[++x]; |
61 ubyte t = state[x]; | |
62 state[x] = state[y]; | |
63 state[y] = t; | |
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.
Thomas Dixon <reikon@reikon.us>
parents:
6
diff
changeset
|
64 output[i] = input[i] ^ state[cast(ubyte)(state[x]+state[y])]; |
0 | 65 } |
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.
Thomas Dixon <reikon@reikon.us>
parents:
6
diff
changeset
|
66 return output; |
0 | 67 } |
68 | |
69 void reset() { | |
70 setup(workingKey); | |
71 } | |
72 | |
73 // Do RC4's key setup in a separate method to ease resetting | |
74 private void setup(ubyte[] key) { | |
75 for (int i = 0; i < 256; i++) | |
76 state[i] = cast(ubyte)i; | |
77 | |
78 x = 0; | |
79 for (int i = 0; i < 256; i++) { | |
80 x += key[i % key.length] + state[i]; | |
81 ubyte t = state[i]; | |
82 state[i] = state[x]; | |
83 state[x] = t; | |
84 } | |
85 x = y = 0; | |
86 } | |
87 | |
88 /** Some RC4 test vectors. */ | |
89 version (UnitTest) { | |
90 unittest { | |
91 static const char[][] test_keys = [ | |
92 "0123456789abcdef", | |
93 "0123456789abcdef", | |
94 "0000000000000000", | |
95 "ef012345", | |
96 "0123456789abcdef" | |
97 ]; | |
98 | |
99 static const char[][] test_plaintexts = [ | |
100 "0123456789abcdef", | |
101 "0000000000000000", | |
102 "0000000000000000", | |
103 "00000000000000000000", | |
104 "01010101010101010101010101010101"~ | |
105 "01010101010101010101010101010101"~ | |
106 "01010101010101010101010101010101"~ | |
107 "01010101010101010101010101010101"~ | |
108 "01010101010101010101010101010101"~ | |
109 "01010101010101010101010101010101"~ | |
110 "01010101010101010101010101010101"~ | |
111 "01010101010101010101010101010101"~ | |
112 "01010101010101010101010101010101"~ | |
113 "01010101010101010101010101010101"~ | |
114 "01010101010101010101010101010101"~ | |
115 "01010101010101010101010101010101"~ | |
116 "01010101010101010101010101010101"~ | |
117 "01010101010101010101010101010101"~ | |
118 "01010101010101010101010101010101"~ | |
119 "01010101010101010101010101010101"~ | |
120 "01010101010101010101010101010101"~ | |
121 "01010101010101010101010101010101"~ | |
122 "01010101010101010101010101010101"~ | |
123 "01010101010101010101010101010101"~ | |
124 "01010101010101010101010101010101"~ | |
125 "01010101010101010101010101010101"~ | |
126 "01010101010101010101010101010101"~ | |
127 "01010101010101010101010101010101"~ | |
128 "01010101010101010101010101010101"~ | |
129 "01010101010101010101010101010101"~ | |
130 "01010101010101010101010101010101"~ | |
131 "01010101010101010101010101010101"~ | |
132 "01010101010101010101010101010101"~ | |
133 "01010101010101010101010101010101"~ | |
134 "01010101010101010101010101010101"~ | |
135 "01010101010101010101010101010101" | |
136 ]; | |
137 | |
138 static const char[][] test_ciphertexts = [ | |
139 "75b7878099e0c596", | |
140 "7494c2e7104b0879", | |
141 "de188941a3375d3a", | |
142 "d6a141a7ec3c38dfbd61", | |
143 "7595c3e6114a09780c4ad452338e1ffd"~ | |
144 "9a1be9498f813d76533449b6778dcad8"~ | |
145 "c78a8d2ba9ac66085d0e53d59c26c2d1"~ | |
146 "c490c1ebbe0ce66d1b6b1b13b6b919b8"~ | |
147 "47c25a91447a95e75e4ef16779cde8bf"~ | |
148 "0a95850e32af9689444fd377108f98fd"~ | |
149 "cbd4e726567500990bcc7e0ca3c4aaa3"~ | |
150 "04a387d20f3b8fbbcd42a1bd311d7a43"~ | |
151 "03dda5ab078896ae80c18b0af66dff31"~ | |
152 "9616eb784e495ad2ce90d7f772a81747"~ | |
153 "b65f62093b1e0db9e5ba532fafec4750"~ | |
154 "8323e671327df9444432cb7367cec82f"~ | |
155 "5d44c0d00b67d650a075cd4b70dedd77"~ | |
156 "eb9b10231b6b5b741347396d62897421"~ | |
157 "d43df9b42e446e358e9c11a9b2184ecb"~ | |
158 "ef0cd8e7a877ef968f1390ec9b3d35a5"~ | |
159 "585cb009290e2fcde7b5ec66d9084be4"~ | |
160 "4055a619d9dd7fc3166f9487f7cb2729"~ | |
161 "12426445998514c15d53a18c864ce3a2"~ | |
162 "b7555793988126520eacf2e3066e230c"~ | |
163 "91bee4dd5304f5fd0405b35bd99c7313"~ | |
164 "5d3d9bc335ee049ef69b3867bf2d7bd1"~ | |
165 "eaa595d8bfc0066ff8d31509eb0c6caa"~ | |
166 "006c807a623ef84c3d33c195d23ee320"~ | |
167 "c40de0558157c822d4b8c569d849aed5"~ | |
168 "9d4e0fd7f379586b4b7ff684ed6a189f"~ | |
169 "7486d49b9c4bad9ba24b96abf924372c"~ | |
170 "8a8fffb10d55354900a77a3db5f205e1"~ | |
171 "b99fcd8660863a159ad4abe40fa48934"~ | |
172 "163ddde542a6585540fd683cbfd8c00f"~ | |
173 "12129a284deacc4cdefe58be7137541c"~ | |
174 "047126c8d49e2755ab181ab7e940b0c0" | |
175 ]; | |
176 | |
177 RC4 r = new RC4(); | |
178 foreach (uint i, char[] test_key; test_keys) { | |
179 ubyte[] buffer = new ubyte[test_plaintexts[i].length>>1]; | |
180 char[] result; | |
181 | |
182 r.init(true, new SymmetricKey(Util.hexToUbytes(test_key))); | |
183 | |
184 // Encryption | |
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.
Thomas Dixon <reikon@reikon.us>
parents:
6
diff
changeset
|
185 buffer = r.process(Util.hexToUbytes(test_plaintexts[i])); |
0 | 186 result = Util.ubytesToHex(buffer); |
187 assert(result == test_ciphertexts[i], | |
2
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
1
diff
changeset
|
188 r.name~": ("~result~") != ("~test_ciphertexts[i]~")"); |
0 | 189 |
190 r.reset(); | |
191 | |
192 // Decryption | |
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.
Thomas Dixon <reikon@reikon.us>
parents:
6
diff
changeset
|
193 buffer = r.process(Util.hexToUbytes(test_ciphertexts[i])); |
0 | 194 result = Util.ubytesToHex(buffer); |
195 assert(result == test_plaintexts[i], | |
6
5cb17e09d685
Minor edits to the unittests of hash functions and ciphers. Added AES and test vectors.
Thomas Dixon <reikon@reikon.us>
parents:
2
diff
changeset
|
196 r.name~": ("~result~") != ("~test_plaintexts[i]~")"); |
0 | 197 } |
198 } | |
199 } | |
200 } |