RuneHive-Game
Loading...
Searching...
No Matches
IsaacCipher.java
Go to the documentation of this file.
1/* Copyright (c) 2009 Graham Edgecombe, Blake Beaupain and Brett Russell
2*
3* More information about Hyperion may be found on this website:
4* http://hyperion.grahamedgecombe.com/
5*
6* Permission is hereby granted, free of charge, to any person obtaining a copy
7* of this software and associated documentation files (the "Software"), to deal
8* in the Software without restriction, including without limitation the rights
9* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10* copies of the Software, and to permit persons to whom the Software is
11* furnished to do so, subject to the following conditions:
12*
13* The above copyright notice and this permission notice shall be included in
14* all copies or substantial portions of the Software.
15*
16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22* THE SOFTWARE.
23*/
24package com.runehive.net.codec;
25
26/**
27* An implementation of an ISAAC cipher. See <a href="http://en.wikipedia.org/wiki/ISAAC_(cipher)">
28* http://en.wikipedia.org/wiki/ISAAC_(cipher)</a> for more information.
29* <p>
30* <p>
31* This implementation is based on the one written by Bob Jenkins, which is available at <a
32* href="http://www.burtleburtle.net/bob/java/rand/Rand.java"> http://www.burtleburtle.net/bob/java/rand/Rand.java</a>.
33*
34* @author Graham Edgecombe
35*/
36public final class IsaacCipher {
37
38 /**
39 * The golden ratio.
40 */
41 private static final int RATIO = 0x9e3779b9;
42
43 /**
44 * The log of the size of the results and memory arrays.
45 */
46 private static final int SIZE_LOG = 8;
47
48 /**
49 * The size of the results and memory arrays.
50 */
51 private static final int SIZE = 1 << SIZE_LOG;
52
53 /**
54 * For pseudorandom lookup.
55 */
56 private static final int MASK = (SIZE - 1) << 2;
57
58 /**
59 * The count through the results.
60 */
61 private int count = 0;
62
63 /**
64 * The results.
65 */
66 private int results[] = new int[SIZE];
67
68 /**
69 * The internal memory state.
70 */
71 private int memory[] = new int[SIZE];
72
73 /**
74 * The accumulator.
75 */
76 private int a;
77
78 /**
79 * The last result.
80 */
81 private int b;
82
83 /**
84 * The counter.
85 */
86 private int c;
87
88 /**
89 * Creates the ISAAC cipher.
90 *
91 * @param seed The seed.
92 */
93 public IsaacCipher(int[] seed) {
94 for (int i = 0; i < seed.length; i++) {
95 results[i] = seed[i];
96 }
97 init(true);
98 }
99
100 /**
101 * Gets the next value.
102 *
103 * @return The next value.
104 */
105 public int getKey() {
106 if (count-- == 0) {
107 isaac();
108 count = SIZE - 1;
109 }
110 return results[count];
111 }
112
113 /**
114 * Generates 256 results.
115 */
116 public void isaac() {
117 int i, j, x, y;
118 b += ++c;
119 for (i = 0, j = SIZE / 2; i < SIZE / 2; ) {
120 x = memory[i];
121 a ^= a << 13;
122 a += memory[j++];
123 memory[i] = y = memory[(x & MASK) >> 2] + a + b;
124 results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
125
126 x = memory[i];
127 a ^= a >>> 6;
128 a += memory[j++];
129 memory[i] = y = memory[(x & MASK) >> 2] + a + b;
130 results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
131
132 x = memory[i];
133 a ^= a << 2;
134 a += memory[j++];
135 memory[i] = y = memory[(x & MASK) >> 2] + a + b;
136 results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
137
138 x = memory[i];
139 a ^= a >>> 16;
140 a += memory[j++];
141 memory[i] = y = memory[(x & MASK) >> 2] + a + b;
142 results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
143 }
144 for (j = 0; j < SIZE / 2; ) {
145 x = memory[i];
146 a ^= a << 13;
147 a += memory[j++];
148 memory[i] = y = memory[(x & MASK) >> 2] + a + b;
149 results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
150
151 x = memory[i];
152 a ^= a >>> 6;
153 a += memory[j++];
154 memory[i] = y = memory[(x & MASK) >> 2] + a + b;
155 results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
156
157 x = memory[i];
158 a ^= a << 2;
159 a += memory[j++];
160 memory[i] = y = memory[(x & MASK) >> 2] + a + b;
161 results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
162
163 x = memory[i];
164 a ^= a >>> 16;
165 a += memory[j++];
166 memory[i] = y = memory[(x & MASK) >> 2] + a + b;
167 results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
168 }
169 }
170
171 /**
172 * Initializes the ISAAC.
173 *
174 * @param flag Flag indicating if we should perform a second pass.
175 */
176 public void init(boolean flag) {
177 int i;
178 int a, b, c, d, e, f, g, h;
179 a = b = c = d = e = f = g = h = RATIO;
180 for (i = 0; i < 4; ++i) {
181 a ^= b << 11;
182 d += a;
183 b += c;
184 b ^= c >>> 2;
185 e += b;
186 c += d;
187 c ^= d << 8;
188 f += c;
189 d += e;
190 d ^= e >>> 16;
191 g += d;
192 e += f;
193 e ^= f << 10;
194 h += e;
195 f += g;
196 f ^= g >>> 4;
197 a += f;
198 g += h;
199 g ^= h << 8;
200 b += g;
201 h += a;
202 h ^= a >>> 9;
203 c += h;
204 a += b;
205 }
206 for (i = 0; i < SIZE; i += 8) {
207 if (flag) {
208 a += results[i];
209 b += results[i + 1];
210 c += results[i + 2];
211 d += results[i + 3];
212 e += results[i + 4];
213 f += results[i + 5];
214 g += results[i + 6];
215 h += results[i + 7];
216 }
217 a ^= b << 11;
218 d += a;
219 b += c;
220 b ^= c >>> 2;
221 e += b;
222 c += d;
223 c ^= d << 8;
224 f += c;
225 d += e;
226 d ^= e >>> 16;
227 g += d;
228 e += f;
229 e ^= f << 10;
230 h += e;
231 f += g;
232 f ^= g >>> 4;
233 a += f;
234 g += h;
235 g ^= h << 8;
236 b += g;
237 h += a;
238 h ^= a >>> 9;
239 c += h;
240 a += b;
241 memory[i] = a;
242 memory[i + 1] = b;
243 memory[i + 2] = c;
244 memory[i + 3] = d;
245 memory[i + 4] = e;
246 memory[i + 5] = f;
247 memory[i + 6] = g;
248 memory[i + 7] = h;
249 }
250 if (flag) {
251 for (i = 0; i < SIZE; i += 8) {
252 a += memory[i];
253 b += memory[i + 1];
254 c += memory[i + 2];
255 d += memory[i + 3];
256 e += memory[i + 4];
257 f += memory[i + 5];
258 g += memory[i + 6];
259 h += memory[i + 7];
260 a ^= b << 11;
261 d += a;
262 b += c;
263 b ^= c >>> 2;
264 e += b;
265 c += d;
266 c ^= d << 8;
267 f += c;
268 d += e;
269 d ^= e >>> 16;
270 g += d;
271 e += f;
272 e ^= f << 10;
273 h += e;
274 f += g;
275 f ^= g >>> 4;
276 a += f;
277 g += h;
278 g ^= h << 8;
279 b += g;
280 h += a;
281 h ^= a >>> 9;
282 c += h;
283 a += b;
284 memory[i] = a;
285 memory[i + 1] = b;
286 memory[i + 2] = c;
287 memory[i + 3] = d;
288 memory[i + 4] = e;
289 memory[i + 5] = f;
290 memory[i + 6] = g;
291 memory[i + 7] = h;
292 }
293 }
294 isaac();
295 count = SIZE;
296 }
297}
void init(boolean flag)
Initializes the ISAAC.
static final int SIZE_LOG
The log of the size of the results and memory arrays.
int memory[]
The internal memory state.
int count
The count through the results.
static final int MASK
For pseudorandom lookup.
static final int RATIO
The golden ratio.
int getKey()
Gets the next value.
void isaac()
Generates 256 results.
IsaacCipher(int[] seed)
Creates the ISAAC cipher.
static final int SIZE
The size of the results and memory arrays.