source: other-projects/trunk/gs3-release-maker/tasks/sshtaskdef/src/mindbright/security/IDEA.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 8.1 KB
Line 
1/******************************************************************************
2 *
3 * Copyright (c) 1998,99 by Mindbright Technology AB, Stockholm, Sweden.
4 * www.mindbright.se, [email protected]
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *****************************************************************************
17 * $Author: mats $
18 * $Date: 1999/10/25 12:05:26 $
19 * $Name: rel1-2-1 $
20 *****************************************************************************/
21/*
22 * !!! Author's comment: The contents of this file is heavily based
23 * upon Tatu Ylonen's c-code (from the ssh1 package). His comments follows:
24 * ...
25 * This code is based on Xuejia Lai: On the Design and Security of Block
26 * Ciphers, ETH Series in Information Processing, vol. 1, Hartung-Gorre
27 * Verlag, Konstanz, Switzerland, 1992. Another source was Bruce
28 * Schneier: Applied Cryptography, John Wiley & Sons, 1994.
29 *
30 * The IDEA mathematical formula may be covered by one or more of the
31 * following patents: PCT/CH91/00117, EP 0 482 154 B1, US Pat. 5,214,703.
32 */
33
34package mindbright.security;
35
36import java.math.BigInteger;
37
38public final class IDEA extends Cipher {
39
40 protected int[] key_schedule = new int[52];
41 protected int IV0 = 0;
42 protected int IV1 = 0;
43
44 public synchronized void encrypt(byte[] src, int srcOff, byte[] dest, int destOff, int len) {
45 int[] out = new int[2];
46 int iv0 = IV0;
47 int iv1 = IV1;
48 int end = srcOff + len;
49
50 for(int si = srcOff, di = destOff; si < end; si += 8, di += 8) {
51 encrypt(iv0, iv1, out);
52 iv0 = out[0];
53 iv1 = out[1];
54 iv0 ^= ((src[si + 3] & 0xff) | ((src[si + 2] & 0xff) << 8) |
55 ((src[si + 1] & 0xff) << 16) | ((src[si] & 0xff) << 24));
56 iv1 ^= ((src[si + 7] & 0xff) | ((src[si + 6] & 0xff) << 8) |
57 ((src[si + 5] & 0xff) << 16) | ((src[si + 4] & 0xff) << 24));
58
59 if(di + 8 <= end) {
60 dest[di+3] = (byte)( iv0 & 0xff);
61 dest[di+2] = (byte)((iv0 >>> 8 ) & 0xff);
62 dest[di+1] = (byte)((iv0 >>> 16) & 0xff);
63 dest[di] = (byte)((iv0 >>> 24) & 0xff);
64 dest[di+7] = (byte)( iv1 & 0xff);
65 dest[di+6] = (byte)((iv1 >>> 8 ) & 0xff);
66 dest[di+5] = (byte)((iv1 >>> 16) & 0xff);
67 dest[di+4] = (byte)((iv1 >>> 24) & 0xff);
68 } else {
69 switch(end - di) {
70 case 7:
71 dest[di+6] = (byte)((iv1 >>> 8) & 0xff);
72 case 6:
73 dest[di+5] = (byte)((iv1 >>> 16) & 0xff);
74 case 5:
75 dest[di+4] = (byte)((iv1 >>> 24) & 0xff);
76 case 4:
77 dest[di+3] = (byte)( iv0 & 0xff);
78 case 3:
79 dest[di+2] = (byte)((iv0 >>> 8) & 0xff);
80 case 2:
81 dest[di+1] = (byte)((iv0 >>> 16) & 0xff);
82 case 1:
83 dest[di] = (byte)((iv0 >>> 24) & 0xff);
84 }
85 }
86 }
87 IV0 = iv0;
88 IV1 = iv1;
89 }
90
91 public synchronized void decrypt(byte[] src, int srcOff, byte[] dest, int destOff, int len) {
92 int[] out = new int[2];
93 int iv0 = IV0;
94 int iv1 = IV1;
95 int plain0, plain1;
96 int end = srcOff + len;
97
98 for(int si = srcOff, di = destOff; si < end; si += 8, di += 8) {
99 decrypt(iv0, iv1, out);
100 iv0 = ((src[si + 3] & 0xff) | ((src[si + 2] & 0xff) << 8) |
101 ((src[si + 1] & 0xff) << 16) | ((src[si] & 0xff) << 24));
102 iv1 = ((src[si + 7] & 0xff) | ((src[si + 6] & 0xff) << 8) |
103 ((src[si + 5] & 0xff) << 16) | ((src[si + 4] & 0xff) << 24));
104 plain0 = out[0] ^ iv0;
105 plain1 = out[1] ^ iv1;
106
107 if(di + 8 <= end) {
108 dest[di+3] = (byte)( plain0 & 0xff);
109 dest[di+2] = (byte)((plain0 >>> 8 ) & 0xff);
110 dest[di+1] = (byte)((plain0 >>> 16) & 0xff);
111 dest[di] = (byte)((plain0 >>> 24) & 0xff);
112 dest[di+7] = (byte)( plain1 & 0xff);
113 dest[di+6] = (byte)((plain1 >>> 8 ) & 0xff);
114 dest[di+5] = (byte)((plain1 >>> 16) & 0xff);
115 dest[di+4] = (byte)((plain1 >>> 24) & 0xff);
116 } else {
117 switch(end - di) {
118 case 7:
119 dest[di+6] = (byte)((plain1 >>> 8) & 0xff);
120 case 6:
121 dest[di+5] = (byte)((plain1 >>> 16) & 0xff);
122 case 5:
123 dest[di+4] = (byte)((plain1 >>> 24) & 0xff);
124 case 4:
125 dest[di+3] = (byte)( plain0 & 0xff);
126 case 3:
127 dest[di+2] = (byte)((plain0 >>> 8) & 0xff);
128 case 2:
129 dest[di+1] = (byte)((plain0 >>> 16) & 0xff);
130 case 1:
131 dest[di] = (byte)((plain0 >>> 24) & 0xff);
132 }
133 }
134 }
135 IV0 = iv0;
136 IV1 = iv1;
137 }
138
139 public void setKey(byte[] key) {
140 int i, ki = 0, j = 0;
141 for(i = 0; i < 8; i++)
142 key_schedule[i] = ((key[2 * i] & 0xff) << 8) | (key[(2 * i) + 1] & 0xff);
143
144 for(i = 8, j = 0; i < 52; i++) {
145 j++;
146 key_schedule[ki + j + 7] = ((key_schedule[ki + (j & 7)] << 9) |
147 (key_schedule[ki + ((j + 1) & 7)] >>> 7)) & 0xffff;
148 ki += j & 8;
149 j &= 7;
150 }
151 }
152
153 public final void encrypt(int l, int r, int[] out) {
154 int t1 = 0, t2 = 0, x1, x2, x3, x4, ki = 0;
155
156 x1 = (l >>> 16);
157 x2 = (l & 0xffff);
158 x3 = (r >>> 16);
159 x4 = (r & 0xffff);
160
161 for(int round = 0; round < 8; round++) {
162 x1 = mulop(x1 & 0xffff, key_schedule[ki++]);
163 x2 = (x2 + key_schedule[ki++]);
164 x3 = (x3 + key_schedule[ki++]);
165 x4 = mulop(x4 & 0xffff, key_schedule[ki++]);
166
167 t1 = (x1 ^ x3);
168 t2 = (x2 ^ x4);
169 t1 = mulop(t1 & 0xffff, key_schedule[ki++]);
170 t2 = (t1 + t2);
171 t2 = mulop(t2 & 0xffff, key_schedule[ki++]);
172 t1 = (t1 + t2);
173
174 x1 = (x1 ^ t2);
175 x4 = (x4 ^ t1);
176 t1 = (t1 ^ x2);
177 x2 = (t2 ^ x3);
178 x3 = t1;
179 }
180
181 t2 = x2;
182 x1 = mulop(x1 & 0xffff, key_schedule[ki++]);
183 x2 = (t1 + key_schedule[ki++]);
184 x3 = ((t2 + key_schedule[ki++]) & 0xffff);
185 x4 = mulop(x4 & 0xffff, key_schedule[ki]);
186
187
188 out[0] = (x1 << 16) | (x2 & 0xffff);
189 out[1] = (x3 << 16) | (x4 & 0xffff);
190 }
191
192 public final void decrypt(int l, int r, int[] out) {
193 encrypt(l, r, out);
194 }
195
196 public static final int mulop(int a, int b) {
197 int ab = a * b;
198 if(ab != 0) {
199 int lo = ab & 0xffff;
200 int hi = (ab >>> 16) & 0xffff;
201 return ((lo - hi) + ((lo < hi) ? 1 : 0));
202 }
203 if(a == 0)
204 return (1 - b);
205 return (1 - a);
206 }
207
208 /* !!! REMOVE DEBUG !!!
209
210 public static void main(String[] argv) {
211 byte[] key = {
212 (byte)0xd3, (byte)0x96, (byte)0xcf, (byte)0x07, (byte)0xfa, (byte)0xa2, (byte)0x64,
213 (byte)0xfe, (byte)0xf3, (byte)0xa2, (byte)0x06, (byte)0x07, (byte)0x1a, (byte)0xb6,
214 (byte)0x13, (byte)0xf6
215 };
216
217 byte[] txt = {
218 (byte)0x2e, (byte)0xbe, (byte)0xc5, (byte)0xac, (byte)0x02, (byte)0xa1, (byte)0xd5,
219 (byte)0x7f, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x1f, (byte)0x43,
220 (byte)0x6f, (byte)0x72, (byte)0x72, (byte)0x75, (byte)0x70, (byte)0x74, (byte)0x65,
221 (byte)0x64, (byte)0x20, (byte)0x63, (byte)0x68, (byte)0x65, (byte)0x63, (byte)0x6b,
222 (byte)0x20, (byte)0x62, (byte)0x79, (byte)0x74, (byte)0x65, (byte)0x73, (byte)0x20,
223 (byte)0x6f, (byte)0x6e, (byte)0x20, (byte)0x69, (byte)0x6e, (byte)0x70, (byte)0x75,
224 (byte)0x74, (byte)0x2e, (byte)0x91, (byte)0x9a, (byte)0x57, (byte)0xdd
225 };
226
227 byte[] enc;
228 byte[] dec;
229
230 System.out.println("key: " + printHex(key));
231 System.out.println("txt: " + printHex(txt));
232
233 IDEA cipher = new IDEA();
234 cipher.setKey(key);
235
236 for(int i = 0; i < 52; i++) {
237 if((i & 0x7) == 0)
238 System.out.println("");
239 System.out.print(" " + cipher.key_schedule[i]);
240 }
241
242 enc = cipher.encrypt(txt);
243 System.out.println("enc: " + printHex(enc));
244
245 cipher = new IDEA();
246 cipher.setKey(key);
247 dec = cipher.decrypt(enc);
248
249 System.out.println("dec: " + printHex(dec));
250 }
251
252 static String printHex(byte[] buf) {
253 byte[] out = new byte[buf.length + 1];
254 out[0] = 0;
255 System.arraycopy(buf, 0, out, 1, buf.length);
256 BigInteger big = new BigInteger(out);
257 return big.toString(16);
258 }
259
260 */
261
262}
263
Note: See TracBrowser for help on using the repository browser.