📄 blowfish.java
字号:
this.workingKey = key;
setKey(this.workingKey);
}
public String getAlgorithmName()
{
return "Blowfish";
}
public final void transformBlock(byte[] in, int inOff, byte[] out, int outOff)
{
if (workingKey == null)
{
throw new IllegalStateException("Blowfish not initialised");
}
if (doEncrypt)
{
encryptBlock(in, inOff, out, outOff);
}
else
{
decryptBlock(in, inOff, out, outOff);
}
}
public void reset()
{
}
public int getBlockSize()
{
return BLOCK_SIZE;
}
// ==================================
// Private Implementation
// ==================================
private int F(int x)
{
return (((S0[(x >>> 24)] + S1[(x >>> 16) & 0xff]) ^ S2[(x >>> 8) & 0xff]) + S3[x & 0xff]);
}
/**
* apply the encryption cycle to each value pair in the table.
*/
private void processTable(int xl, int xr, int[] table)
{
int size = table.length;
for (int s = 0; s < size; s += 2)
{
xl ^= P[0];
for (int i = 1; i < ROUNDS; i += 2)
{
xr ^= F(xl) ^ P[i];
xl ^= F(xr) ^ P[i + 1];
}
xr ^= P[ROUNDS + 1];
table[s] = xr;
table[s + 1] = xl;
xr = xl; // end of cycle swap
xl = table[s];
}
}
private void setKey(byte[] key)
{
/*
* - comments are from _Applied Crypto_, Schneier, p338 please be
* careful comparing the two, AC numbers the arrays from 1, the enclosed
* code from 0.
*
* (1) Initialise the S-boxes and the P-array, with a fixed string This
* string contains the hexadecimal digits of pi (3.141...)
*/
System.arraycopy(KS0, 0, S0, 0, SBOX_SK);
System.arraycopy(KS1, 0, S1, 0, SBOX_SK);
System.arraycopy(KS2, 0, S2, 0, SBOX_SK);
System.arraycopy(KS3, 0, S3, 0, SBOX_SK);
System.arraycopy(KP, 0, P, 0, P_SZ);
/*
* (2) Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with
* the second 32-bits of the key, and so on for all bits of the key (up
* to P[17]). Repeatedly cycle through the key bits until the entire
* P-array has been XOR-ed with the key bits
*/
int keyLength = key.length;
int keyIndex = 0;
for (int i = 0; i < P_SZ; i++)
{
// get the 32 bits of the key, in 4 * 8 bit chunks
int data = 0x0000000;
for (int j = 0; j < 4; j++)
{
// create a 32 bit block
data = (data << 8) | (key[keyIndex++] & 0xff);
// wrap when we get to the end of the key
if (keyIndex >= keyLength)
{
keyIndex = 0;
}
}
// XOR the newly created 32 bit chunk onto the P-array
P[i] ^= data;
}
/*
* (3) Encrypt the all-zero string with the Blowfish algorithm, using
* the subkeys described in (1) and (2)
*
* (4) Replace P1 and P2 with the output of step (3)
*
* (5) Encrypt the output of step(3) using the Blowfish algorithm, with
* the modified subkeys.
*
* (6) Replace P3 and P4 with the output of step (5)
*
* (7) Continue the process, replacing all elements of the P-array and
* then all four S-boxes in order, with the output of the continuously
* changing Blowfish algorithm
*/
processTable(0, 0, P);
processTable(P[P_SZ - 2], P[P_SZ - 1], S0);
processTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1);
processTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2);
processTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3);
}
/**
* Encrypt the given input starting at the given offset and place the result
* in the provided buffer starting at the given offset. The input will be an
* exact multiple of our blocksize.
*/
private void encryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
int xl = BytesTo32bits(src, srcIndex);
int xr = BytesTo32bits(src, srcIndex + 4);
xl ^= P[0];
for (int i = 1; i < ROUNDS; i += 2)
{
xr ^= F(xl) ^ P[i];
xl ^= F(xr) ^ P[i + 1];
}
xr ^= P[ROUNDS + 1];
Bits32ToBytes(xr, dst, dstIndex);
Bits32ToBytes(xl, dst, dstIndex + 4);
}
/**
* Decrypt the given input starting at the given offset and place the result
* in the provided buffer starting at the given offset. The input will be an
* exact multiple of our blocksize.
*/
private void decryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
int xl = BytesTo32bits(src, srcIndex);
int xr = BytesTo32bits(src, srcIndex + 4);
xl ^= P[ROUNDS + 1];
for (int i = ROUNDS; i > 0; i -= 2)
{
xr ^= F(xl) ^ P[i];
xl ^= F(xr) ^ P[i - 1];
}
xr ^= P[0];
Bits32ToBytes(xr, dst, dstIndex);
Bits32ToBytes(xl, dst, dstIndex + 4);
}
private int BytesTo32bits(byte[] b, int i)
{
return ((b[i] & 0xff) << 24) | ((b[i + 1] & 0xff) << 16) | ((b[i + 2] & 0xff) << 8) | ((b[i + 3] & 0xff));
}
private void Bits32ToBytes(int in, byte[] b, int offset)
{
b[offset + 3] = (byte) in;
b[offset + 2] = (byte) (in >> 8);
b[offset + 1] = (byte) (in >> 16);
b[offset] = (byte) (in >> 24);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -