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

📄 idea.java

📁 面向应用的智能安全代理平台和工具包是一个综合网络应用的安全共性需求而设计和实现的一个通用性的网络信息安全应用支撑平台
💻 JAVA
字号:
package au.net.aba.crypto.provider;

/*
 * $Id: IDEA.java,v 1.13 1999/02/17 01:40:13 leachbj Exp $
 * $Author: leachbj $
 *
 * Copyright (C) 1996-1998 Australian Business Access Pty Ltd.
 * All rights reserved.
 * 
 * Use, modification, copying and distribution of this software is subject the
 * terms and conditions of the ABA Public Licence. See the file
 * "PUBLIC_LICENCE" for additional information.
 *
 * If you have not received a copy of the Public Licence, you must destroy all
 * copies of this file immediately. 
 *
 * $Source: /aba/CVSROOT/jdk1.1/src/au.net.aba/crypto/provider/IDEA.java,v $
 * $Revision: 1.13 $
 * $Date: 1999/02/17 01:40:13 $
 * $State: Exp $
 */

import javax.crypto.*;
import javax.crypto.spec.*;

import java.security.*;

import java.security.*;
import java.security.spec.*;

import au.net.aba.crypto.spec.*;

/**
 * A class that provides IDEA public key encryption operations,
 * such as encoding data and generating keys.
 */
public class IDEA extends BlockCipher
{
	public final static String ident = "$Id: IDEA.java,v 1.13 1999/02/17 01:40:13 leachbj Exp $";

	//====================================
	// Useful constants
	//====================================

	protected static final int	Rounds =	8;

	protected static final int	UserKeyLen = 8;    // 8wrds =128bit
	protected static final int	KeyLen = (Rounds * 6) + 4;

	protected static final int	MulModulus =	0x10001;
	protected static final int	MulMask =	0xffff;

	/**
	 * The data bytes that constitute the key.
	 */
	public int[]	encr = null;
	public int[]	decr = null;

	int AddInv(
		int x )
	{
		return (-x) & MulMask;
	}
	//==================================
	// Private Implementation
	//==================================

	int bytes2int(
		byte[]	b,
		int	off)
	{
		return ((b[off] << 8) & 0xff00) + (b[off+1] & 0xff);
	}
	/**
	 * 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.
	 */
	protected int decryptBlock(
		byte[] src,
		int srcIndex,
		int len,
		byte[] dst,
		int dstIndex)
	throws BadPaddingException
	{
		if (len != BLOCK_SIZE)
		{
			throw new BadPaddingException("Datasize less than block size.");
		}

		do_idea_1blk(decr, src, srcIndex, dst, dstIndex);

		return BLOCK_SIZE;
	}
	void do_idea_1blk(
		int[]	key,
		byte[]	src,
		int	soff,
		byte[]	dst, 
		int	doff)
	{
		int	round = Rounds;
		int	koff = 0;
		int	x0, x1, x2, x3, t0, t1;

		x0 = bytes2int(src, soff+0);
		x1 = bytes2int(src, soff+2);
		x2 = bytes2int(src, soff+4);
		x3 = bytes2int(src, soff+6);

		do
		{
			x0 = MulMod16(x0, key[koff++]);
			x1 += key[koff++];		x1 &= MulMask;
			x2 += key[koff++];		x2 &= MulMask;
			x3 = MulMod16(x3, key[koff++]);

			t0 = x2;
			x2 = MulMod16(x0^x2, key[koff++]);
			t1 = x1;
			x1 = MulMod16((x1^x3)+x2, key[koff++]);
			x2 += x1;			x2 &= MulMask;

			x0 ^= x1;
			x3 ^= x2;
			x1 ^= t0;
			x2 ^= t1;
		}
		while (--round > 0);

		x0 = MulMod16(x0, key[koff++]);
		t0 = x1;
		x1 = x2 + key[koff++];			x1 &= MulMask;
		x2 = t0 + key[koff++];			x2 &= MulMask;
		x3 = MulMod16(x3, key[koff++]);

		dst[doff++] = (byte) ((x0 >>> 8) & 0xff);
		dst[doff++] = (byte) (x0 & 0xff);
		dst[doff++] = (byte) ((x1 >>> 8) & 0xff);
		dst[doff++] = (byte) (x1 & 0xff);
		dst[doff++] = (byte) ((x2 >>> 8) & 0xff);
		dst[doff++] = (byte) (x2 & 0xff);
		dst[doff++] = (byte) ((x3 >>> 8) & 0xff);
		dst[doff++] = (byte) (x3 & 0xff);
	}
	/**
	 * 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.
	 */
	protected int encryptBlock(
		byte[] src,
		int srcIndex,
		int len,
		byte[] dst,
		int dstIndex)
	throws IllegalBlockSizeException
	{
		if (len != BLOCK_SIZE)
		{
			throw new IllegalBlockSizeException("Datasize less than block size.");
		}

		do_idea_1blk(encr, src, srcIndex, dst, dstIndex);

		return BLOCK_SIZE;
	}
	int MulInv(
		int x)
	{
		int t0, t1, q, y;

		x &= MulMask;

		if (x <= 1)		// Since zero and one are self inverse
			return x;

		t1 = (int) (0x10001L / x); // Since x >= 2, the result is 16bit
		y = (int) (0x10001L % x);
		if (y == 1)
			return (1 - t1) & MulMask;

		t0 = 1;
		do
		{
			q = (x / y);
			x %= y;
			t0 = (t0 + (q * t1)) & MulMask;
			if (x == 1)
				return t0;
			q = y / x;
			y = y % x;
			t1 = (t1 + (q * t0)) & MulMask;
		}
		while (y != 1);

		return (1 - t1) & MulMask;
	}
	int MulMod16(
		int	a,
		int	b)
	{
		int	p;

		a &= MulMask;
		b &= MulMask;

		if (a == 0)
		{
			a = MulModulus - b;
		}
		else if (b == 0)
		{
			a = MulModulus - a;
		}
		else
		{
			// a *= b;
			// b = a >>> 16;
			// if ((a & MulMask) >= b)
				// a -= b;
			// else
				// a += MulModulus - b;

			p = a * b;
			b = p & MulMask;
			a = p >>> 16;
			a = b - a + (b < a ? 1 : 0);
		}
		
		return a & MulMask;
	}
	/**
	 * prepare key data necessary for decryption.
	 */
	void prepare_decr()
	{
		int	lo, hi,
			i;
		int	t;

		decr = new int[KeyLen];

		lo = 0;
		hi = 6 * Rounds;

		t = MulInv(encr[lo]);
		decr[lo++] = MulInv(encr[hi]);
		decr[hi++] = t;

		t = AddInv(encr[lo]);
		decr[lo++] = AddInv(encr[hi]);
		decr[hi++] = t;

		t = AddInv(encr[lo]);
		decr[lo++] = AddInv(encr[hi]);
		decr[hi++] = t;

		t = MulInv(encr[lo]);
		decr[lo++] = MulInv(encr[hi]);
		decr[hi] = t;

		for (i = (Rounds - 1) / 2; i != 0; i--)
		{
			t = encr[lo];
			decr[lo++] = encr[hi -= 5];
			decr[hi++] = t;

			t = encr[lo];
			decr[lo++] = encr[hi];
			decr[hi] = t;

			t = MulInv(encr[lo]);
			decr[lo++] = MulInv(encr[hi -= 5]);
			decr[hi++] = t;

			t = AddInv(encr[lo]);
			decr[lo++] = AddInv(encr[++hi]);
			decr[hi--] = t;

			t = AddInv(encr[lo]);
			decr[lo++] = AddInv(encr[hi]);
			decr[hi++] = t;

			t = MulInv(encr[lo]);
			decr[lo++] = MulInv(encr[++hi]);
			decr[hi] = t;
		}

		if (Rounds % 2 == 0)
		{
			t = encr[lo];
			decr[lo++] = encr[hi -= 5];
			decr[hi++] = t;

			t = encr[lo];
			decr[lo++] = encr[hi];
			decr[hi] = t;

			decr[lo] = MulInv(encr[lo]);
			lo++;
			t = AddInv(encr[lo]);
			decr[lo] = AddInv(encr[lo + 1]);
			lo++;

			decr[lo++] = t;
			decr[lo] = MulInv(encr[lo]);
		}
		else
		{
			decr[lo] = encr[lo];
			lo++;
			decr[lo] = encr[lo];
		}
	}
	/**
	 * prepare the key data necessary for encryption
	 *
	 * @param		the user supplied data
	 */
	void prepare_encr(
		short[]		data)
	{
		int	i;

		encr = new int[KeyLen];

		for (i = 0; i < UserKeyLen; i++)
		{
			encr[i] = data[i] & MulMask;
		}

		for (i = UserKeyLen; i < KeyLen; i++)
		{
			if ((i & 7) < 6)	// encr[8-13], encr[16-21], ...
			{
				encr[i] = ((encr[i - 7] & 127) << 9
					| encr[i - 6] >>> 7) & MulMask;
			}
			else if ((i & 7) == 6)	 // encr[14], encr[22], ...
			{
				encr[i] = (((encr[i - 7] & 127) << 9)
					| (encr[i - 14] >>> 7)) & MulMask;
			}
			else 		// encr[15], encr[21], ...
			{
				encr[i] = ((encr[i - 15] & 127) << 9
					| encr[i-14] >>> 7) & MulMask;
			}
		}
	}
	/**
	 * Re-key the cipher.  If the provided Key is not compatible
	 * with this cipher the exception should throw an InvalidKeyException.
	 *
	 * @param inKey      the key to be used.
	 * @exception InvalidKeyException if the key is of the wrong type.
	 */
	protected void setKey(Key inKey)
	throws InvalidKeyException
	{
		if (!((inKey instanceof IDEAKey)
				|| (inKey instanceof SecretKeySpec)))
		{
			throw new InvalidKeyException("not an IDEA Key");
		}

		byte[] rawKey = inKey.getEncoded();

		// Now make sure the key is long enough and convert it to
		//	short[] from byte[].

		short[] data = new short[UserKeyLen];
		byte[] bdata = new byte[UserKeyLen * 2];

		for (int length = 0; length < (UserKeyLen * 2);
						length += rawKey.length)
		{
			System.arraycopy(rawKey, 0,
					bdata, length,
					rawKey.length < (bdata.length-length)
						?  rawKey.length :
						   bdata.length - length);
		}

		for (int length = 0; length < UserKeyLen; length++)
		{
			data[length] = (short) (
					    ((bdata[2*length] << 8) & 0xff00) +
					     (bdata[(2*length) + 1] & 0xff)
					);
		}

		// Build the encryption  - we always need this
		prepare_encr(data);

		// if necessary build the decryption schedule
		if (mode == Cipher.DECRYPT_MODE)
		{
			prepare_decr(); 
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -