?? blowfish.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 Bruce Schneier's (who is the inventor of the blowfish-algorithm) * c-code found in his book: * Bruce Schneier: Applied Cryptography 2nd ed., John Wiley & Sons, 1996 */package de.mud.ssh;import java.math.BigInteger;public final class Blowfish extends Cipher { protected int[] S0 = new int[256]; protected int[] S1 = new int[256]; protected int[] S2 = new int[256]; protected int[] S3 = new int[256]; protected int[] P = new int[18]; private int IV0; private int IV1; public Blowfish() { } // Set key of this Blowfish from a String public void setKey(String skey) { byte[] key = skey.getBytes(); setKey(key); } // Set key of this Blowfish from a bytearray public void setKey(byte[] key) { int i, j, k, len = key.length; int temp; int L, R; int[] output = new int[2]; System.arraycopy(blowfish_pbox, 0, P, 0, 18); System.arraycopy(blowfish_sbox, 0, S0, 0, 256); System.arraycopy(blowfish_sbox, 256, S1, 0, 256); System.arraycopy(blowfish_sbox, 512, S2, 0, 256); System.arraycopy(blowfish_sbox, 768, S3, 0, 256); // Actual subkey generation // for(j = 0, i = 0; i < 16 + 2; i++) { temp = (( (key[j] & 0xff) << 24) | ( (key[(j + 1) % len] & 0xff) << 16) | ( (key[(j + 2) % len] & 0xff) << 8) | ( (key[(j + 3) % len] & 0xff))); P[i] = P[i] ^ temp; j = (j + 4) % len; } L = 0; R = 0; for(i = 0; i < 16 + 2; i += 2) { encrypt(L, R, output); L = output[0]; R = output[1]; P[i] = L; P[i + 1] = R; } for(j = 0; j < 256; j += 2) { encrypt(L, R, output); L = output[0]; R = output[1]; S0[j] = L; S0[j + 1] = R; } for(j = 0; j < 256; j += 2) { encrypt(L, R, output); L = output[0]; R = output[1]; S1[j] = L; S1[j + 1] = R; } for(j = 0; j < 256; j += 2) { encrypt(L, R, output); L = output[0]; R = output[1]; S2[j] = L; S2[j + 1] = R; } for(j = 0; j < 256; j += 2) { encrypt(L, R, output); L = output[0]; R = output[1]; S3[j] = L; S3[j + 1] = R; } IV0 = 0; 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) { iv0 ^= ((src[si] & 0xff) | ((src[si + 1] & 0xff) << 8) | ((src[si + 2] & 0xff) << 16) | ((src[si + 3] & 0xff) << 24)); iv1 ^= ((src[si + 4] & 0xff) | ((src[si + 5] & 0xff) << 8) | ((src[si + 6] & 0xff) << 16) | ((src[si + 7] & 0xff) << 24)); encrypt(iv0, iv1, out); iv0 = out[0]; iv1 = out[1]; dest[di] = (byte)( iv0 & 0xff); dest[di+1] = (byte)((iv0 >>> 8 ) & 0xff); dest[di+2] = (byte)((iv0 >>> 16) & 0xff); dest[di+3] = (byte)((iv0 >>> 24) & 0xff); dest[di+4] = (byte)( iv1 & 0xff); dest[di+5] = (byte)((iv1 >>> 8 ) & 0xff); dest[di+6] = (byte)((iv1 >>> 16) & 0xff); dest[di+7] = (byte)((iv1 >>> 24) & 0xff); } IV0 = iv0; IV1 = iv1; } public void encrypt(int xL, int xR, int[] out) { int L, R; L = xL; R = xR; L ^= P[0]; R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[1]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[2]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[3]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[4]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[5]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[6]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[7]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[8]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[9]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[10]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[11]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[12]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[13]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[14]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[15]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[16]); R ^= P[17]; out[0] = R; out[1] = L; } 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 d0; int d1; int end = srcOff + len; for(int si = srcOff, di = destOff; si < end; si += 8, di += 8) { d0 = ((src[si] & 0xff) | ((src[si + 1] & 0xff) << 8) | ((src[si + 2] & 0xff) << 16) | ((src[si + 3] & 0xff) << 24)); d1 = ((src[si + 4] & 0xff) | ((src[si + 5] & 0xff) << 8) | ((src[si + 6] & 0xff) << 16) | ((src[si + 7] & 0xff) << 24)); decrypt(d0, d1, out); iv0 ^= out[0]; iv1 ^= out[1]; dest[di] = (byte)( iv0 & 0xff); dest[di+1] = (byte)((iv0 >>> 8 ) & 0xff); dest[di+2] = (byte)((iv0 >>> 16) & 0xff); dest[di+3] = (byte)((iv0 >>> 24) & 0xff); dest[di+4] = (byte)( iv1 & 0xff); dest[di+5] = (byte)((iv1 >>> 8 ) & 0xff); dest[di+6] = (byte)((iv1 >>> 16) & 0xff); dest[di+7] = (byte)((iv1 >>> 24) & 0xff); iv0 = d0; iv1 = d1; } IV0 = iv0; IV1 = iv1; } public int[] decrypt(int xL, int xR, int[] out) { int L, R; L = xL; R = xR; L ^= P[17]; R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[16]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[15]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[14]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[13]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[12]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[11]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[10]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[9]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[8]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[7]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[6]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[5]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[4]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[3]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[2]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[1]); R ^= P[0]; out[0] = R; out[1] = L; return out; }/* Blowfish's P and S -boxes, respectively. These were taken from Bruce Schneier's public-domain implementation. */ final static int[] blowfish_pbox = { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b }; final static int[] blowfish_sbox = { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -