⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blowfish.java

📁 thinking in java4 src
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		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 + -