?? idea.java
字號:
/****************************************************************************** * * Copyright (c) 1998,99 by Mindbright Technology AB, Stockholm, Sweden. * www.mindbright.se, info@mindbright.se * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * ***************************************************************************** * $Author: marcus $ * $Date: 2000/12/20 21:48:30 $ * $Name: $ *****************************************************************************//* * !!! Author's comment: The contents of this file is heavily based * upon Tatu Ylonen's c-code (from the ssh1 package). His comments follows: * ... * This code is based on Xuejia Lai: On the Design and Security of Block * Ciphers, ETH Series in Information Processing, vol. 1, Hartung-Gorre * Verlag, Konstanz, Switzerland, 1992. Another source was Bruce * Schneier: Applied Cryptography, John Wiley & Sons, 1994. * * The IDEA mathematical formula may be covered by one or more of the * following patents: PCT/CH91/00117, EP 0 482 154 B1, US Pat. 5,214,703. */package de.mud.ssh;import java.math.BigInteger;public final class IDEA extends Cipher { protected int[] key_schedule = new int[52]; protected int IV0 = 0; protected int IV1 = 0; public synchronized void encrypt(byte[] src, int srcOff, byte[] dest, int destOff, int len) { int[] out = new int[2]; int iv0 = IV0; int iv1 = IV1; int end = srcOff + len; for(int si = srcOff, di = destOff; si < end; si += 8, di += 8) { encrypt(iv0, iv1, out); iv0 = out[0]; iv1 = out[1]; iv0 ^= ((src[si + 3] & 0xff) | ((src[si + 2] & 0xff) << 8) | ((src[si + 1] & 0xff) << 16) | ((src[si] & 0xff) << 24)); iv1 ^= ((src[si + 7] & 0xff) | ((src[si + 6] & 0xff) << 8) | ((src[si + 5] & 0xff) << 16) | ((src[si + 4] & 0xff) << 24)); if(di + 8 <= end) { dest[di+3] = (byte)( iv0 & 0xff); dest[di+2] = (byte)((iv0 >>> 8 ) & 0xff); dest[di+1] = (byte)((iv0 >>> 16) & 0xff); dest[di] = (byte)((iv0 >>> 24) & 0xff); dest[di+7] = (byte)( iv1 & 0xff); dest[di+6] = (byte)((iv1 >>> 8 ) & 0xff); dest[di+5] = (byte)((iv1 >>> 16) & 0xff); dest[di+4] = (byte)((iv1 >>> 24) & 0xff); } else { switch(end - di) { case 7: dest[di+6] = (byte)((iv1 >>> 8) & 0xff); case 6: dest[di+5] = (byte)((iv1 >>> 16) & 0xff); case 5: dest[di+4] = (byte)((iv1 >>> 24) & 0xff); case 4: dest[di+3] = (byte)( iv0 & 0xff); case 3: dest[di+2] = (byte)((iv0 >>> 8) & 0xff); case 2: dest[di+1] = (byte)((iv0 >>> 16) & 0xff); case 1: dest[di] = (byte)((iv0 >>> 24) & 0xff); } } } IV0 = iv0; IV1 = iv1; } public synchronized void decrypt(byte[] src, int srcOff, byte[] dest, int destOff, int len) { int[] out = new int[2]; int iv0 = IV0; int iv1 = IV1; int plain0, plain1; int end = srcOff + len; for(int si = srcOff, di = destOff; si < end; si += 8, di += 8) { decrypt(iv0, iv1, out); iv0 = ((src[si + 3] & 0xff) | ((src[si + 2] & 0xff) << 8) | ((src[si + 1] & 0xff) << 16) | ((src[si] & 0xff) << 24)); iv1 = ((src[si + 7] & 0xff) | ((src[si + 6] & 0xff) << 8) | ((src[si + 5] & 0xff) << 16) | ((src[si + 4] & 0xff) << 24)); plain0 = out[0] ^ iv0; plain1 = out[1] ^ iv1; if(di + 8 <= end) { dest[di+3] = (byte)( plain0 & 0xff); dest[di+2] = (byte)((plain0 >>> 8 ) & 0xff); dest[di+1] = (byte)((plain0 >>> 16) & 0xff); dest[di] = (byte)((plain0 >>> 24) & 0xff); dest[di+7] = (byte)( plain1 & 0xff); dest[di+6] = (byte)((plain1 >>> 8 ) & 0xff); dest[di+5] = (byte)((plain1 >>> 16) & 0xff); dest[di+4] = (byte)((plain1 >>> 24) & 0xff); } else { switch(end - di) { case 7: dest[di+6] = (byte)((plain1 >>> 8) & 0xff); case 6: dest[di+5] = (byte)((plain1 >>> 16) & 0xff); case 5: dest[di+4] = (byte)((plain1 >>> 24) & 0xff); case 4: dest[di+3] = (byte)( plain0 & 0xff); case 3: dest[di+2] = (byte)((plain0 >>> 8) & 0xff); case 2: dest[di+1] = (byte)((plain0 >>> 16) & 0xff); case 1: dest[di] = (byte)((plain0 >>> 24) & 0xff); } } } IV0 = iv0; IV1 = iv1; } public void setKey(byte[] key) { int i, ki = 0, j = 0; for(i = 0; i < 8; i++) key_schedule[i] = ((key[2 * i] & 0xff) << 8) | (key[(2 * i) + 1] & 0xff); for(i = 8, j = 0; i < 52; i++) { j++; key_schedule[ki + j + 7] = ((key_schedule[ki + (j & 7)] << 9) | (key_schedule[ki + ((j + 1) & 7)] >>> 7)) & 0xffff; ki += j & 8; j &= 7; } } public final void encrypt(int l, int r, int[] out) { int t1 = 0, t2 = 0, x1, x2, x3, x4, ki = 0; x1 = (l >>> 16); x2 = (l & 0xffff); x3 = (r >>> 16); x4 = (r & 0xffff); for(int round = 0; round < 8; round++) { x1 = mulop(x1 & 0xffff, key_schedule[ki++]); x2 = (x2 + key_schedule[ki++]); x3 = (x3 + key_schedule[ki++]); x4 = mulop(x4 & 0xffff, key_schedule[ki++]); t1 = (x1 ^ x3); t2 = (x2 ^ x4); t1 = mulop(t1 & 0xffff, key_schedule[ki++]); t2 = (t1 + t2); t2 = mulop(t2 & 0xffff, key_schedule[ki++]); t1 = (t1 + t2); x1 = (x1 ^ t2); x4 = (x4 ^ t1); t1 = (t1 ^ x2); x2 = (t2 ^ x3); x3 = t1; } t2 = x2; x1 = mulop(x1 & 0xffff, key_schedule[ki++]); x2 = (t1 + key_schedule[ki++]); x3 = ((t2 + key_schedule[ki++]) & 0xffff); x4 = mulop(x4 & 0xffff, key_schedule[ki]); out[0] = (x1 << 16) | (x2 & 0xffff); out[1] = (x3 << 16) | (x4 & 0xffff); } public final void decrypt(int l, int r, int[] out) { encrypt(l, r, out); } public static final int mulop(int a, int b) { int ab = a * b; if(ab != 0) { int lo = ab & 0xffff; int hi = (ab >>> 16) & 0xffff; return ((lo - hi) + ((lo < hi) ? 1 : 0)); } if(a == 0) return (1 - b); return (1 - a); } /* !!! REMOVE DEBUG !!! public static void main(String[] argv) { byte[] key = { (byte)0xd3, (byte)0x96, (byte)0xcf, (byte)0x07, (byte)0xfa, (byte)0xa2, (byte)0x64, (byte)0xfe, (byte)0xf3, (byte)0xa2, (byte)0x06, (byte)0x07, (byte)0x1a, (byte)0xb6, (byte)0x13, (byte)0xf6 }; byte[] txt = { (byte)0x2e, (byte)0xbe, (byte)0xc5, (byte)0xac, (byte)0x02, (byte)0xa1, (byte)0xd5, (byte)0x7f, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x1f, (byte)0x43, (byte)0x6f, (byte)0x72, (byte)0x72, (byte)0x75, (byte)0x70, (byte)0x74, (byte)0x65, (byte)0x64, (byte)0x20, (byte)0x63, (byte)0x68, (byte)0x65, (byte)0x63, (byte)0x6b, (byte)0x20, (byte)0x62, (byte)0x79, (byte)0x74, (byte)0x65, (byte)0x73, (byte)0x20, (byte)0x6f, (byte)0x6e, (byte)0x20, (byte)0x69, (byte)0x6e, (byte)0x70, (byte)0x75, (byte)0x74, (byte)0x2e, (byte)0x91, (byte)0x9a, (byte)0x57, (byte)0xdd }; byte[] enc; byte[] dec; System.out.println("key: " + printHex(key)); System.out.println("txt: " + printHex(txt)); IDEA cipher = new IDEA(); cipher.setKey(key); for(int i = 0; i < 52; i++) { if((i & 0x7) == 0) System.out.println(""); System.out.print(" " + cipher.key_schedule[i]); } enc = cipher.encrypt(txt); System.out.println("enc: " + printHex(enc)); cipher = new IDEA(); cipher.setKey(key); dec = cipher.decrypt(enc); System.out.println("dec: " + printHex(dec)); } static String printHex(byte[] buf) { byte[] out = new byte[buf.length + 1]; out[0] = 0; System.arraycopy(buf, 0, out, 1, buf.length); BigInteger big = new BigInteger(out); return big.toString(16); } */}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -