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

📄 safer.java

📁 另一个使用java编写的加密通用算法包
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * @param  ps  The desired new variant identifier for this cipher.     * @throw  IllegalStateException If this cipher is not uninitialised.     * @throw  InvalidParameterException If the variant identifier is invalid.     */    public void setVariant (String ps) {        if (getState() != UNINITIALIZED)            throw new IllegalStateException("Cipher not in UNINITIALIZED state");        if (ps.equalsIgnoreCase("SK128") || ps.equalsIgnoreCase("SK-128"))            variant = SK128_VARIANT;        else if (ps.equalsIgnoreCase("SK64") || ps.equalsIgnoreCase("SK-64"))            variant = SK64_VARIANT;        else if (ps.equalsIgnoreCase("K128") || ps.equalsIgnoreCase("K-128"))            variant = K128_VARIANT;        else if (ps.equalsIgnoreCase("K64") || ps.equalsIgnoreCase("K-64"))            variant = K64_VARIANT;        else            throw new InvalidParameterException();    }    /**     * Gets the variant for this cipher ("SK-128", "SK-64", "K-128", or "K-64").     */    public String getVariant() {        switch (variant) {            case SK128_VARIANT: return "SK-128";            case SK64_VARIANT:  return "SK-64";            case K128_VARIANT:  return "K-128";            case K64_VARIANT:   return "K-64";            default:            throw new InternalError("variant = " + variant);        }    }    /**     * Encryption algorithm.     *     * @param  in       contains the plaintext block.     * @param  inOff    start index within input where data should be considered.     * @param  out      will contain the ciphertext block.     * @param  outOff   index in out where ciphertext starts.     */    private void blockEncrypt (byte[] in, int inOff, byte[] out, int outOff) {        int k = 0,            round = sKey[k++];                    if (MAX_NOF_ROUNDS < round)            round = MAX_NOF_ROUNDS;                    int t,            a = in[inOff++],            b = in[inOff++],            c = in[inOff++],            d = in[inOff++],            e = in[inOff++],            f = in[inOff++],            g = in[inOff++],            h = in[inOff++];                    for (int i = 0; i < round; i++) {            a ^= sKey[k++];            b += sKey[k++];            c += sKey[k++];            d ^= sKey[k++];            e ^= sKey[k++];            f += sKey[k++];            g += sKey[k++];            h ^= sKey[k++];                        a = EXP[a & 0xFF] + sKey[k++];            b = LOG[b & 0xFF] ^ sKey[k++];            c = LOG[c & 0xFF] ^ sKey[k++];            d = EXP[d & 0xFF] + sKey[k++];            e = EXP[e & 0xFF] + sKey[k++];            f = LOG[f & 0xFF] ^ sKey[k++];            g = LOG[g & 0xFF] ^ sKey[k++];            h = EXP[h & 0xFF] + sKey[k++];                        b += a;        a += b;            //    PHT(a, b);            d += c;        c += d;            //    PHT(c, d);            f += e;        e += f;            //    PHT(e, f);            h += g;        g += h;            //    PHT(g, h);            c += a;        a += c;            //    PHT(a, c);            g += e;        e += g;            //    PHT(e, g);            d += b;        b += d;            //    PHT(b, d);            h += f;        f += h;            //    PHT(f, h);            e += a;        a += e;            //    PHT(a, e);            f += b;        b += f;            //    PHT(b, f);            g += c;        c += g;            //    PHT(c, g);            h += d;        d += h;            //    PHT(d, h);                        t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t;        }        out[outOff++] = (byte)(a ^ sKey[k++]);        out[outOff++] = (byte)(b + sKey[k++]);        out[outOff++] = (byte)(c + sKey[k++]);        out[outOff++] = (byte)(d ^ sKey[k++]);        out[outOff++] = (byte)(e ^ sKey[k++]);        out[outOff++] = (byte)(f + sKey[k++]);        out[outOff++] = (byte)(g + sKey[k++]);        out[outOff++] = (byte)(h ^ sKey[k++]);    }    /**     * Decryption algorithm.     *     * @param  in       contains the ciphertext block.     * @param  inOff    index within input where cipher data should be considered     * @param  out      will contain the plaintext block.     * @param  outOff   index in out where plaintext starts.     */    private void blockDecrypt (byte[] in, int inOff, byte[] out, int outOff) {        int round = sKey[0];        if (MAX_NOF_ROUNDS < round)            round = MAX_NOF_ROUNDS;                    int t,            a = in[inOff++],            b = in[inOff++],            c = in[inOff++],            d = in[inOff++],            e = in[inOff++],            f = in[inOff++],            g = in[inOff++],            h = in[inOff++];        int k = BLOCK_SIZE * (1 + 2 * round);                h ^= sKey[k];        g -= sKey[--k];        f -= sKey[--k];        e ^= sKey[--k];        d ^= sKey[--k];        c -= sKey[--k];        b -= sKey[--k];        a ^= sKey[--k];                for (int i = 0; i < round; i++) {            t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t;                        a -= e;        e -= a;            //    IPHT(a, e);            b -= f;        f -= b;            //    IPHT(b, f);            c -= g;        g -= c;            //    IPHT(c, g);            d -= h;        h -= d;            //    IPHT(d, h);            a -= c;        c -= a;            //    IPHT(a, c);            e -= g;        g -= e;            //    IPHT(e, g);            b -= d;        d -= b;            //    IPHT(b, d);            f -= h;        h -= f;            //    IPHT(f, h);            a -= b;        b -= a;            //    IPHT(a, b);            c -= d;        d -= c;            //    IPHT(c, d);            e -= f;        f -= e;            //    IPHT(e, f);            g -= h;        h -= g;            //    IPHT(g, h);            h -= sKey[--k];            g ^= sKey[--k];            f ^= sKey[--k];            e -= sKey[--k];            d -= sKey[--k];            c ^= sKey[--k];            b ^= sKey[--k];            a -= sKey[--k];                        h = LOG[h & 0xFF] ^ sKey[--k];            g = EXP[g & 0xFF] - sKey[--k];            f = EXP[f & 0xFF] - sKey[--k];            e = LOG[e & 0xFF] ^ sKey[--k];            d = LOG[d & 0xFF] ^ sKey[--k];            c = EXP[c & 0xFF] - sKey[--k];            b = EXP[b & 0xFF] - sKey[--k];            a = LOG[a & 0xFF] ^ sKey[--k];        }            out[outOff++] = (byte)a;        out[outOff++] = (byte)b;        out[outOff++] = (byte)c;        out[outOff++] = (byte)d;        out[outOff++] = (byte)e;        out[outOff++] = (byte)f;        out[outOff++] = (byte)g;        out[outOff++] = (byte)h;    }        /**     * Expands a userKey to a working SAFER key (sKey).     * <p>     * The key bytes are fist extracted from the user-key and formatted     * into a 16-byte array (128 bits) which is then passed to the     * Safer_Expand_Userkey() method. The length of the array is known     * by the currently set variant of this object. If there isn't enough     * bytes in the user key to make a valid SAFER user-key (64 or 128     * bits), the user-key is either trunctated or copied appropriately     * to obtain enough bytes for the Safer_Expand_Userkey() method. An     * exception is thrown only if the user-key is null;     */    private synchronized void makeKey (Key key)    throws KeyException {        byte[] keyBytes = key.getEncoded();        if (keyBytes == null) throw new KeyException("Invalid SAFER key");        byte[] userKey = new byte[2 * BLOCK_SIZE];        int keyLen = keyBytes.length,            len = 2 * BLOCK_SIZE,            userKeyLenSoFar = 0;        while (len >= keyLen) {            System.arraycopy(keyBytes, 0, userKey, userKeyLenSoFar, keyLen);            len -= keyLen;            userKeyLenSoFar += keyLen;        }        System.arraycopy(keyBytes, 0, userKey, userKeyLenSoFar, len);                byte[]            key1 = new byte[BLOCK_SIZE],            key2 = new byte[BLOCK_SIZE];        System.arraycopy(userKey, 0, key1, 0, BLOCK_SIZE);        System.arraycopy(userKey, BLOCK_SIZE, key2, 0, BLOCK_SIZE);        Safer_Expand_Userkey(key1, key2);    }    /**     * Expands a user-selected key of length 64 bits or 128 bits to the     * encryption / decryption sKey.     *     * Note: SAFER K-64 and SAFER SK-64 with a user-selected key 'z' of     * length 64 bits are identical to SAFER K-128 and SAFER SK-128 with     * a user-selected key 'z z' of length 128 bits, respectively.     *     * @param    userkey_1    contains the first 64 bits of user key.     * @param    userkey_2    contains the second 64 bits of user key.     */    private void Safer_Expand_Userkey (byte[] userkey_1, byte[] userkey_2) {        // 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_1, userkey_2, rounds, isStrong()));                    return;                } catch (Error error) {                    native_finalize();                    native_lock = null;if (DEBUG && debuglevel > 0) debug(error + ". Will use 100% Java.");                }            }        }        byte[]            ka = new byte[BLOCK_SIZE + 1],            kb = new byte[BLOCK_SIZE + 1];        int k = 0;        sKey[k++] = (byte)rounds;        for (int j = 0; j < BLOCK_SIZE; j++) {            ka[j] = (byte)(userkey_1[j] << 5 |(userkey_1[j] & 0xFF) >>> 3);            ka[BLOCK_SIZE] ^= ka[j];            sKey[k++] = userkey_2[j];            kb[j] = userkey_2[j];            kb[BLOCK_SIZE] ^= kb[j];        }        for (int i = 1; i <= rounds; i++) {            for (int j = 0; j < BLOCK_SIZE + 1; j++) {                ka[j] = (byte)(ka[j] << 6 |(ka[j] & 0xFF) >>> 2);                kb[j] = (byte)(kb[j] << 6 |(kb[j] & 0xFF) >>> 2);            }            for (int j = 0; j < BLOCK_SIZE; j++)                if (isStrong())                    sKey[k++] = (ka[(j + 2 * i - 1) % (BLOCK_SIZE + 1)]                        + EXP[EXP[18 * i + j + 1]]) & 0xFF;                else                    sKey[k++] = (ka[j] + EXP[EXP[18 * i + j + 1]]) & 0xFF;            for (int j = 0; j < BLOCK_SIZE; j++)                if (isStrong())                    sKey[k++] = (kb[(j + 2 * i) % (BLOCK_SIZE + 1)]                        + EXP[EXP[18 * i + j + 10]]) & 0xFF;                else                    sKey[k++] = (kb[j] + EXP[EXP[18 * i + j + 10]]) & 0xFF;        }    }    /** Returns true if this cipher should use a strengthened key schedule. */    private boolean isStrong () { return (variant < K128_VARIANT); }}

⌨️ 快捷键说明

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