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

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2004-03-06 22:44:06