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

📄 ideaengine.java

📁 kmlnjlkj nlkjlkjkljl okopokipoipo oipipipo i
💻 JAVA
字号:
package org.bouncycastle.crypto.engines;import org.bouncycastle.crypto.BlockCipher;import org.bouncycastle.crypto.CipherParameters;import org.bouncycastle.crypto.DataLengthException;import org.bouncycastle.crypto.params.KeyParameter;/** * A class that provides a basic International Data Encryption Algorithm (IDEA) engine. * <p> * This implementation is based on the "HOWTO: INTERNATIONAL DATA ENCRYPTION ALGORITHM" * implementation summary by Fauzan Mirza (F.U.Mirza@sheffield.ac.uk). (baring 1 typo at the * end of the mulinv function!). * <p> * It can be found at ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/idea/ * <p> * Note 1: This algorithm is patented in the USA, Japan, and Europe including * at least Austria, France, Germany, Italy, Netherlands, Spain, Sweden, Switzerland * and the United Kingdom. Non-commercial use is free, however any commercial * products are liable for royalties. Please see * <a href="http://www.mediacrypt.com">www.mediacrypt.com</a> for * further details. This announcement has been included at the request of * the patent holders. * <p> * Note 2: Due to the requests concerning the above, this algorithm is now only * included in the extended Bouncy Castle provider and JCE signed jars. It is * not included in the default distributions. */public class IDEAEngine    implements BlockCipher{    protected static final int  BLOCK_SIZE = 8;    private int[]               workingKey = null;    /**     * standard constructor.     */    public IDEAEngine()    {    }    /**     * initialise an IDEA cipher.     *     * @param forEncryption whether or not we are for encryption.     * @param params the parameters required to set up the cipher.     * @exception IllegalArgumentException if the params argument is     * inappropriate.     */    public void init(        boolean           forEncryption,        CipherParameters  params)    {        if (params instanceof KeyParameter)        {            workingKey = generateWorkingKey(forEncryption,                                  ((KeyParameter)params).getKey());            return;        }        throw new IllegalArgumentException("invalid parameter passed to IDEA init - " + params.getClass().getName());    }    public String getAlgorithmName()    {        return "IDEA";    }    public int getBlockSize()    {        return BLOCK_SIZE;    }    public int processBlock(        byte[] in,        int inOff,        byte[] out,        int outOff)    {        if (workingKey == null)        {            throw new IllegalStateException("IDEA engine not initialised");        }        if ((inOff + BLOCK_SIZE) > in.length)        {            throw new DataLengthException("input buffer too short");        }        if ((outOff + BLOCK_SIZE) > out.length)        {            throw new DataLengthException("output buffer too short");        }        ideaFunc(workingKey, in, inOff, out, outOff);        return BLOCK_SIZE;    }    public void reset()    {    }    private static final int    MASK = 0xffff;    private static final int    BASE = 0x10001;    private int bytesToWord(        byte[]  in,        int     inOff)    {        return ((in[inOff] << 8) & 0xff00) + (in[inOff + 1] & 0xff);    }    private void wordToBytes(        int     word,        byte[]  out,        int     outOff)    {        out[outOff] = (byte)(word >>> 8);        out[outOff + 1] = (byte)word;    }    /**     * return x = x * y where the multiplication is done modulo     * 65537 (0x10001) (as defined in the IDEA specification) and     * a zero input is taken to be 65536 (0x10000).     *     * @param x the x value     * @param y the y value     * @return x = x * y     */    private int mul(        int x,        int y)    {        if (x == 0)        {            x = (BASE - y);        }        else if (y == 0)        {            x = (BASE - x);        }        else        {            int     p = x * y;            y = p & MASK;            x = p >>> 16;            x = y - x + ((y < x) ? 1 : 0);        }        return x & MASK;    }    private void ideaFunc(        int[]   workingKey,        byte[]  in,        int     inOff,        byte[]  out,        int     outOff)    {        int     x0, x1, x2, x3, t0, t1;        int     keyOff = 0;        x0 = bytesToWord(in, inOff);        x1 = bytesToWord(in, inOff + 2);        x2 = bytesToWord(in, inOff + 4);        x3 = bytesToWord(in, inOff + 6);        for (int round = 0; round < 8; round++)        {            x0 = mul(x0, workingKey[keyOff++]);            x1 += workingKey[keyOff++];            x1 &= MASK;            x2 += workingKey[keyOff++];            x2 &= MASK;            x3 = mul(x3, workingKey[keyOff++]);            t0 = x1;            t1 = x2;            x2 ^= x0;            x1 ^= x3;            x2 = mul(x2, workingKey[keyOff++]);            x1 += x2;            x1 &= MASK;            x1 = mul(x1, workingKey[keyOff++]);            x2 += x1;            x2 &= MASK;            x0 ^= x1;            x3 ^= x2;            x1 ^= t1;            x2 ^= t0;        }        wordToBytes(mul(x0, workingKey[keyOff++]), out, outOff);        wordToBytes(x2 + workingKey[keyOff++], out, outOff + 2);  /* NB: Order */        wordToBytes(x1 + workingKey[keyOff++], out, outOff + 4);        wordToBytes(mul(x3, workingKey[keyOff]), out, outOff + 6);    }    /**     * The following function is used to expand the user key to the encryption     * subkey. The first 16 bytes are the user key, and the rest of the subkey     * is calculated by rotating the previous 16 bytes by 25 bits to the left,     * and so on until the subkey is completed.     */    private int[] expandKey(        byte[]  uKey)    {        int[]   key = new int[52];        if (uKey.length < 16)        {            byte[]  tmp = new byte[16];            System.arraycopy(uKey, 0, tmp, tmp.length - uKey.length, uKey.length);            uKey = tmp;        }        for (int i = 0; i < 8; i++)        {            key[i] = bytesToWord(uKey, i * 2);        }        for (int i = 8; i < 52; i++)        {            if ((i & 7) < 6)            {                key[i] = ((key[i - 7] & 127) << 9 | key[i - 6] >> 7) & MASK;            }            else if ((i & 7) == 6)            {                key[i] = ((key[i - 7] & 127) << 9 | key[i - 14] >> 7) & MASK;            }            else            {                key[i] = ((key[i - 15] & 127) << 9 | key[i - 14] >> 7) & MASK;            }        }        return key;    }    /**     * This function computes multiplicative inverse using Euclid's Greatest     * Common Divisor algorithm. Zero and one are self inverse.     * <p>     * i.e. x * mulInv(x) == 1 (modulo BASE)     */    private int mulInv(        int x)    {        int t0, t1, q, y;                if (x < 2)        {            return x;        }        t0 = 1;        t1 = BASE / x;        y  = BASE % x;        while (y != 1)        {            q = x / y;            x = x % y;            t0 = (t0 + (t1 * q)) & MASK;            if (x == 1)            {                return t0;            }            q = y / x;            y = y % x;            t1 = (t1 + (t0 * q)) & MASK;        }        return (1 - t1) & MASK;    }    /**     * Return the additive inverse of x.     * <p>     * i.e. x + addInv(x) == 0     */    int addInv(        int x)    {        return (0 - x) & MASK;    }        /**     * The function to invert the encryption subkey to the decryption subkey.     * It also involves the multiplicative inverse and the additive inverse functions.     */    private int[] invertKey(        int[] inKey)    {        int     t1, t2, t3, t4;        int     p = 52;                 /* We work backwards */        int[]   key = new int[52];        int     inOff = 0;            t1 = mulInv(inKey[inOff++]);        t2 = addInv(inKey[inOff++]);        t3 = addInv(inKey[inOff++]);        t4 = mulInv(inKey[inOff++]);        key[--p] = t4;        key[--p] = t3;        key[--p] = t2;        key[--p] = t1;            for (int round = 1; round < 8; round++)        {            t1 = inKey[inOff++];            t2 = inKey[inOff++];            key[--p] = t2;            key[--p] = t1;                t1 = mulInv(inKey[inOff++]);            t2 = addInv(inKey[inOff++]);            t3 = addInv(inKey[inOff++]);            t4 = mulInv(inKey[inOff++]);            key[--p] = t4;            key[--p] = t2; /* NB: Order */            key[--p] = t3;            key[--p] = t1;        }        t1 = inKey[inOff++];        t2 = inKey[inOff++];        key[--p] = t2;        key[--p] = t1;            t1 = mulInv(inKey[inOff++]);        t2 = addInv(inKey[inOff++]);        t3 = addInv(inKey[inOff++]);        t4 = mulInv(inKey[inOff]);        key[--p] = t4;        key[--p] = t3;        key[--p] = t2;        key[--p] = t1;        return key;    }        private int[] generateWorkingKey(        boolean forEncryption,        byte[]  userKey)    {        if (forEncryption)        {            return expandKey(userKey);        }        else        {            return invertKey(expandKey(userKey));        }    }}

⌨️ 快捷键说明

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