cast5.java

来自「jpeg2000编解码」· Java 代码 · 共 1,317 行 · 第 1/5 页

JAVA
1,317
字号
//    private int[]//        Km = new int[16],       // this cipher's masking subkeys//        Kr = new int[16];       // and rotation ones    /** Masking session keys. */    private int        Km0, Km1, Km2,  Km3,  Km4,  Km5,  Km6,  Km7,        Km8, Km9, Km10, Km11, Km12, Km13, Km14, Km15;            /** Rotation session keys. */    private int        Kr0, Kr1, Kr2,  Kr3,  Kr4,  Kr5,  Kr6,  Kr7,        Kr8, Kr9, Kr10, Kr11, Kr12, Kr13, Kr14, Kr15;// Constructor, finalizer, and clone()//............................................................................    /**     * Constructs a CAST5 cipher object, in the UNINITIALIZED state.     * This calls the Cipher constructor with <i>implBuffering</i> false,     * <i>implPadding</i> false and the provider set to "Cryptix".     *     * @see java.security.Cipher#UNINITIALIZED     */    public CAST5 () {        super(false, false, "Cryptix");        link();    }    /**     * Cleans up resources used by this instance, if necessary.     */    protected final void finalize() {        if (native_lock != null) {            synchronized(native_lock) {                String error = native_finalize(); // may be called more than once                if (error != null)                    debug(error + " in native_finalize");            }        }    }    /**     * Always throws a CloneNotSupportedException (cloning of ciphers is not     * supported for security reasons).     */    public final Object clone() throws CloneNotSupportedException {        throw new CloneNotSupportedException();    }// Implementation of JCE methods//............................................................................        /**     * <b>SPI</b>: Returns the length of an input block, in bytes.     *     * @return the length in bytes of an input block for this cipher.     */    protected int engineBlockSize () { return BLOCK_SIZE; }    /**     * <b>SPI</b>: Initializes this cipher for encryption, using the     * specified key.     *     * @param key   the key to use for encryption.     * @exception  KeyException     *     when one of the following occurs:<ul>     *         <li>The user key object is null;     *         <li>The decoded byte array form of the user key is     *         zero long;     *         <li>The decoded user key is shorter than 40 bits or     *         longer than 128 bits.</ul>     */    protected void engineInitEncrypt (Key key)    throws KeyException {        makeKey(key);    }    /**     * <b>SPI</b>: Initializes this cipher for decryption, using the     * specified key.     *     * @param key   the key to use for decryption.     * @exception  KeyException     *     when one of the following occurs:<ul>     *         <li>The user key object is null;     *         <li>The decoded byte array form of the user key is     *         zero long;     *         <li>The decoded user key is shorter than 40 bits or     *         longer than 128 bits.</ul>     */    protected void engineInitDecrypt (Key key)    throws KeyException {        makeKey(key);    }    /**     * <b>SPI</b>: This is the main engine method for updating data.     * <p>     * <i>in</i> and <i>out</i> may be the same array, and the input and output     * regions may overlap.     *     * @param  in           the input data.     * @param  inOffset     the offset into in specifying where the data starts.     * @param  inLen        the length of the subarray.     * @param  out          the output array.     * @param  outOffset    the offset indicating where to start writing into     *                      the out array.     * @return the number of bytes written.     * @exception CryptixException if the native library is being used, and it     *                      reports an error.     */    protected int    engineUpdate(byte[] in, int inOffset, int inLen, byte[] out, int outOffset) {        if (inLen < 0) throw new IllegalArgumentException("inLen < 0");        int blockCount = inLen / BLOCK_SIZE;        inLen = blockCount * BLOCK_SIZE;        boolean doEncrypt = (getState() == ENCRYPT);        // Avoid overlapping input and output regions.        if (in == out && (outOffset >= inOffset && outOffset < (long)inOffset+inLen ||                          inOffset >= outOffset && inOffset < (long)outOffset+inLen)) {            byte[] newin = new byte[inLen];            System.arraycopy(in, inOffset, newin, 0, inLen);            in = newin;            inOffset = 0;        }        if (native_lock != null) {            synchronized(native_lock) {                // If in == null || out == 0, evaluating their lengths will throw a                // NullPointerException.                if (inOffset < 0 || (long)inOffset + inLen > in.length ||                    outOffset < 0 || (long)outOffset + inLen > out.length)                    throw new ArrayIndexOutOfBoundsException(getAlgorithm() +                        ": Arguments to native_crypt would cause a buffer overflow");                // In future, we may pass more than one block to native_crypt to reduce                // native method overhead.                for (int i = 0; i < blockCount; i++) {                    if (0 == native_crypt(native_cookie, in, inOffset, out, outOffset,                                          doEncrypt))                        throw new CryptixException(getAlgorithm() + ": Error in native code");                    inOffset += BLOCK_SIZE;                    outOffset += BLOCK_SIZE;                }            }        } else if (doEncrypt) { // state == ENCRYPT            for (int i = 0; i < blockCount; i++) {                blockEncrypt(in, inOffset, out, outOffset);                inOffset += BLOCK_SIZE;                outOffset += BLOCK_SIZE;            }        } else {                // state == DECRYPT            for (int i = 0; i < blockCount; i++) {                blockDecrypt(in, inOffset, out, outOffset);                inOffset += BLOCK_SIZE;                outOffset += BLOCK_SIZE;            }        }        return inLen;    }// Own methods//............................................................................        /**     * Expands a user key to a working CAST5 128-bit key --by     * padding it with 0x00 if it's shorter than 16 bytes--     * and generates the masking and rotation keypairs for     * the block cipher.     *     * @param  key The user key object.     * @exception  KeyException     *     when one of the following occurs:<ul>     *         <li>The user key object is null;     *         <li>The decoded byte array form of the user key is     *         zero long;     *         <li>The decoded user key is shorter than 40 bits or     *         longer than 128 bits.</ul>     */    private void makeKey (Key key)    throws KeyException {        byte[] userkey = key.getEncoded();        if (userkey == null)            throw new KeyException(getAlgorithm() + ": Null user key");        int len = userkey.length;        if (len < 5 || len > 16)            throw new KeyException(getAlgorithm() + ": Invalid user key length");        // If native library available then use it. If not or if        // native method returned error then revert to 100% Java.        if (native_lock != null) {            synchronized(native_lock) {                try {                    linkStatus.check(native_ks(native_cookie, userkey));                    return;                } catch (Error error) {                    native_finalize();                    native_lock = null;if (DEBUG && debuglevel > 0) debug(error + ". Will use 100% Java.");                }            }        }        rounds = (len < 11) ? MIN_NOF_ROUNDS : MAX_NOF_ROUNDS;        byte[] kk = new byte[16];        System.arraycopy(userkey, 0, kk, 0, len);        int x0x1x2x3 = (kk[ 0] & 0xFF) << 24 | (kk[ 1] & 0xFF) << 16 |                       (kk[ 2] & 0xFF) <<  8 | (kk[ 3] & 0xFF),            x4x5x6x7 = (kk[ 4] & 0xFF) << 24 | (kk[ 5] & 0xFF) << 16 |                       (kk[ 6] & 0xFF) <<  8 | (kk[ 7] & 0xFF),            x8x9xAxB = (kk[ 8] & 0xFF) << 24 | (kk[ 9] & 0xFF) << 16 |                       (kk[10] & 0xFF) <<  8 | (kk[11] & 0xFF),            xCxDxExF = (kk[12] & 0xFF) << 24 | (kk[13] & 0xFF) << 16 |                       (kk[14] & 0xFF) <<  8 | (kk[15] & 0xFF),            z0z1z2z3, z4z5z6z7, z8z9zAzB, zCzDzEzF,            z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, zA, zB, zC, zD, zE, zF,            x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xA, xB, xC, xD, xE, xF;        int[] b;        b = unscramble(x0x1x2x3); x0 = b[0]; x1 = b[1]; x2 = b[2]; x3 = b[3];        b = unscramble(x4x5x6x7); x4 = b[0]; x5 = b[1]; x6 = b[2]; x7 = b[3];        b = unscramble(x8x9xAxB); x8 = b[0]; x9 = b[1]; xA = b[2]; xB = b[3];        b = unscramble(xCxDxExF); xC = b[0]; xD = b[1]; xE = b[2]; xF = b[3];        z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];        b = unscramble(z0z1z2z3); z0 = b[0]; z1 = b[1]; z2 = b[2]; z3 = b[3];        z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];        b = unscramble(z4z5z6z7); z4 = b[0]; z5 = b[1]; z6 = b[2]; z7 = b[3];        z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];        b = unscramble(z8z9zAzB); z8 = b[0]; z9 = b[1]; zA = b[2]; zB = b[3];        zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];        b = unscramble(zCzDzEzF); zC = b[0]; zD = b[1]; zE = b[2]; zF = b[3];        Km0 = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2];        Km1 = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6];        Km2 = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9];        Km3 = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC];        x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];        b = unscramble(x0x1x2x3); x0 = b[0]; x1 = b[1]; x2 = b[2]; x3 = b[3];        x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];        b = unscramble(x4x5x6x7); x4 = b[0]; x5 = b[1]; x6 = b[2]; x7 = b[3];        x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];        b = unscramble(x8x9xAxB); x8 = b[0]; x9 = b[1]; xA = b[2]; xB = b[3];        xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];        b = unscramble(xCxDxExF); xC = b[0]; xD = b[1]; xE = b[2]; xF = b[3];        Km4 = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8];        Km5 = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD];        Km6 = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3];        Km7 = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7];

⌨️ 快捷键说明

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