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

📄 aes.java

📁 JAVA 数学程序库 提供常规的数值计算程序包
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                    ((Se[(temp       ) & 0xff] & 0xff) <<  8) |
                    ((Se[(temp >>> 24)       ] & 0xff));
                temp ^= rcon[r++];
            } else if (Nk == 8 && n == 4) {
                temp =
                    ((Se[(temp >>> 24)       ]       ) << 24) |
                    ((Se[(temp >>> 16) & 0xff] & 0xff) << 16) |
                    ((Se[(temp >>>  8) & 0xff] & 0xff) <<  8) |
                    ((Se[(temp       ) & 0xff] & 0xff));
            }
            rek[i] = rek[i - Nk] ^ temp;
        }
        temp = 0;
    }


    /**
     * Compute the decryption schedule from the encryption schedule .
     */
    private final void invertKey() {
        int d = 0, e = 4*Nr, w;
	    /*
         * apply the inverse MixColumn transform to all round keys
         * but the first and the last:
         */
        rdk[d    ] = rek[e    ];
        rdk[d + 1] = rek[e + 1];
        rdk[d + 2] = rek[e + 2];
        rdk[d + 3] = rek[e + 3];
	    d += 4;
	    e -= 4;
	    for (int r = 1; r < Nr; r++) {
            w = rek[e    ];
	    	rdk[d    ] =
	    		Td0[Se[(w >>> 24)       ] & 0xff] ^
	    		Td1[Se[(w >>> 16) & 0xff] & 0xff] ^
	    		Td2[Se[(w >>>  8) & 0xff] & 0xff] ^
	    		Td3[Se[(w       ) & 0xff] & 0xff];
            w = rek[e + 1];
	    	rdk[d + 1] =
	    		Td0[Se[(w >>> 24)       ] & 0xff] ^
	    		Td1[Se[(w >>> 16) & 0xff] & 0xff] ^
	    		Td2[Se[(w >>>  8) & 0xff] & 0xff] ^
	    		Td3[Se[(w       ) & 0xff] & 0xff];
            w = rek[e + 2];
	    	rdk[d + 2] =
	    		Td0[Se[(w >>> 24)       ] & 0xff] ^
	    		Td1[Se[(w >>> 16) & 0xff] & 0xff] ^
	    		Td2[Se[(w >>>  8) & 0xff] & 0xff] ^
	    		Td3[Se[(w       ) & 0xff] & 0xff];
            w = rek[e + 3];
	    	rdk[d + 3] =
	    		Td0[Se[(w >>> 24)       ] & 0xff] ^
	    		Td1[Se[(w >>> 16) & 0xff] & 0xff] ^
	    		Td2[Se[(w >>>  8) & 0xff] & 0xff] ^
	    		Td3[Se[(w       ) & 0xff] & 0xff];
            d += 4;
            e -= 4;
	    }
        rdk[d    ] = rek[e    ];
        rdk[d + 1] = rek[e + 1];
        rdk[d + 2] = rek[e + 2];
        rdk[d + 3] = rek[e + 3];
    }

    /**
     * Setup the AES key schedule for encryption, decryption, or both.
     *
     * @param   cipherKey   the cipher key (128, 192, or 256 bits).
     * @param   keyBits     size of the cipher key in bits.
     * @param   direction   cipher direction (DIR_ENCRYPT, DIR_DECRYPT, or DIR_BOTH).
     */
    public final void makeKey(byte[] cipherKey, int keySize, int direction)
            throws RuntimeException {
        // check key size:
        switch (keySize) {
        case 16:
        case 24:
        case 32:
            keySize <<= 3; // keySize is now in bits
            break;
        case 128:
        case 192:
        case 256:
            break;
        default:
            throw new RuntimeException("Invalid AES key size (" + keySize + ")");
        }
        Nk = keySize >>> 5;
        Nr = Nk + 6;
        Nw = 4*(Nr + 1);
        rek = new int[Nw];
        rdk = new int[Nw];
        if ((direction & DIR_BOTH) != 0) {
            expandKey(cipherKey);
            /*
            for (int r = 0; r <= Nr; r++) {
            	System.out.print("RK" + r + "=");
            	for (int i = 0; i < 4; i++) {
            		int w = rek[4*r + i];
            		System.out.print(" " + Integer.toHexString(w));
            	}
            	System.out.println();
            }
            */
            if ((direction & DIR_DECRYPT) != 0) {
                invertKey();
            }
        }
    }

    /**
     * Setup the AES key schedule (any cipher direction).
     *
     * @param   cipherKey   the cipher key (128, 192, or 256 bits).
     * @param   keyBits     size of the cipher key in bits.
     */
    public final void makeKey(byte[] cipherKey, int keyBits)
            throws RuntimeException {
        makeKey(cipherKey, keyBits, DIR_BOTH);
    }

    /**
     * Encrypt exactly one block (BLOCK_SIZE bytes) of plaintext.
     *
     * @param   pt          plaintext block.
     * @param   ct          ciphertext block.
     */
    public final void encrypt(byte[] pt, byte[] ct) {
        /*
	     * map byte array block to cipher state
	     * and add initial round key:
	     */
        int k = 0, v;
        int t0   = ((pt[ 0]       ) << 24 |
                    (pt[ 1] & 0xff) << 16 |
                    (pt[ 2] & 0xff) <<  8 |
                    (pt[ 3] & 0xff)        ) ^ rek[0];
        int t1   = ((pt[ 4]       ) << 24 |
                    (pt[ 5] & 0xff) << 16 |
                    (pt[ 6] & 0xff) <<  8 |
                    (pt[ 7] & 0xff)        ) ^ rek[1];
        int t2   = ((pt[ 8]       ) << 24 |
                    (pt[ 9] & 0xff) << 16 |
                    (pt[10] & 0xff) <<  8 |
                    (pt[11] & 0xff)        ) ^ rek[2];
        int t3   = ((pt[12]       ) << 24 |
                    (pt[13] & 0xff) << 16 |
                    (pt[14] & 0xff) <<  8 |
                    (pt[15] & 0xff)        ) ^ rek[3];
        /*
	     * Nr - 1 full rounds:
	     */
        for (int r = 1; r < Nr; r++) {
            k += 4;
            int a0 =
                Te0[(t0 >>> 24)       ] ^
                Te1[(t1 >>> 16) & 0xff] ^
                Te2[(t2 >>>  8) & 0xff] ^
                Te3[(t3       ) & 0xff] ^
                rek[k    ];
            int a1 =
                Te0[(t1 >>> 24)       ] ^
                Te1[(t2 >>> 16) & 0xff] ^
                Te2[(t3 >>>  8) & 0xff] ^
                Te3[(t0       ) & 0xff] ^
                rek[k + 1];
            int a2 =
                Te0[(t2 >>> 24)       ] ^
                Te1[(t3 >>> 16) & 0xff] ^
                Te2[(t0 >>>  8) & 0xff] ^
                Te3[(t1       ) & 0xff] ^
                rek[k + 2];
            int a3 =
                Te0[(t3 >>> 24)       ] ^
                Te1[(t0 >>> 16) & 0xff] ^
                Te2[(t1 >>>  8) & 0xff] ^
                Te3[(t2       ) & 0xff] ^
                rek[k + 3];
            t0 = a0; t1 = a1; t2 = a2; t3 = a3;
        }
        /*
         * last round lacks MixColumn:
         */
        k += 4;

        v = rek[k    ];
        ct[ 0] = (byte)(Se[(t0 >>> 24)       ] ^ (v >>> 24));
        ct[ 1] = (byte)(Se[(t1 >>> 16) & 0xff] ^ (v >>> 16));
                ct[ 2] = (byte)(Se[(t2 >>>  8) & 0xff] ^ (v >>>  8));
        ct[ 3] = (byte)(Se[(t3       ) & 0xff] ^ (v       ));

        v = rek[k + 1];
        ct[ 4] = (byte)(Se[(t1 >>> 24)       ] ^ (v >>> 24));
        ct[ 5] = (byte)(Se[(t2 >>> 16) & 0xff] ^ (v >>> 16));
        ct[ 6] = (byte)(Se[(t3 >>>  8) & 0xff] ^ (v >>>  8));
        ct[ 7] = (byte)(Se[(t0       ) & 0xff] ^ (v       ));

        v = rek[k + 2];
        ct[ 8] = (byte)(Se[(t2 >>> 24)       ] ^ (v >>> 24));
        ct[ 9] = (byte)(Se[(t3 >>> 16) & 0xff] ^ (v >>> 16));
        ct[10] = (byte)(Se[(t0 >>>  8) & 0xff] ^ (v >>>  8));
        ct[11] = (byte)(Se[(t1       ) & 0xff] ^ (v       ));

        v = rek[k + 3];
        ct[12] = (byte)(Se[(t3 >>> 24)       ] ^ (v >>> 24));
        ct[13] = (byte)(Se[(t0 >>> 16) & 0xff] ^ (v >>> 16));
        ct[14] = (byte)(Se[(t1 >>>  8) & 0xff] ^ (v >>>  8));
        ct[15] = (byte)(Se[(t2       ) & 0xff] ^ (v       ));
    }

    /**
     * Decrypt exactly one block (BLOCK_SIZE bytes) of ciphertext.
     *
     * @param   ct          ciphertext block.
     * @param   pt          plaintext block.
     */
    public final void decrypt(byte[] ct, byte[] pt) {
        /*
	     * map byte array block to cipher state
	     * and add initial round key:
	     */
        int k = 0, v;
        int t0 =   ((ct[ 0]       ) << 24 |
                    (ct[ 1] & 0xff) << 16 |
                    (ct[ 2] & 0xff) <<  8 |
                    (ct[ 3] & 0xff)        ) ^ rdk[0];
        int t1 =   ((ct[ 4]       ) << 24 |
                    (ct[ 5] & 0xff) << 16 |
                    (ct[ 6] & 0xff) <<  8 |
                    (ct[ 7] & 0xff)        ) ^ rdk[1];
        int t2 =   ((ct[ 8]       ) << 24 |
                    (ct[ 9] & 0xff) << 16 |
                    (ct[10] & 0xff) <<  8 |
                    (ct[11] & 0xff)        ) ^ rdk[2];
        int t3 =   ((ct[12]       ) << 24 |
                    (ct[13] & 0xff) << 16 |
                    (ct[14] & 0xff) <<  8 |
                    (ct[15] & 0xff)        ) ^ rdk[3];
        /*
	     * Nr - 1 full rounds:
	     */
        for (int r = 1; r < Nr; r++) {
            k += 4;
            int a0 =
                Td0[(t0 >>> 24)       ] ^
                Td1[(t3 >>> 16) & 0xff] ^
                Td2[(t2 >>>  8) & 0xff] ^
                Td3[(t1       ) & 0xff] ^
                rdk[k    ];
            int a1 =
                Td0[(t1 >>> 24)       ] ^
                Td1[(t0 >>> 16) & 0xff] ^
                Td2[(t3 >>>  8) & 0xff] ^
                Td3[(t2       ) & 0xff] ^
                rdk[k + 1];
            int a2 =
                Td0[(t2 >>> 24)       ] ^
                Td1[(t1 >>> 16) & 0xff] ^
                Td2[(t0 >>>  8) & 0xff] ^
                Td3[(t3       ) & 0xff] ^
                rdk[k + 2];
            int a3 =
                Td0[(t3 >>> 24)       ] ^
                Td1[(t2 >>> 16) & 0xff] ^
                Td2[(t1 >>>  8) & 0xff] ^
                Td3[(t0       ) & 0xff] ^
                rdk[k + 3];
            t0 = a0; t1 = a1; t2 = a2; t3 = a3;
        }
        /*
         * last round lacks MixColumn:
         */
        k += 4;

        v = rdk[k    ];
        pt[ 0] = (byte)(Sd[(t0 >>> 24)       ] ^ (v >>> 24));
        pt[ 1] = (byte)(Sd[(t3 >>> 16) & 0xff] ^ (v >>> 16));
        pt[ 2] = (byte)(Sd[(t2 >>>  8) & 0xff] ^ (v >>>  8));
        pt[ 3] = (byte)(Sd[(t1       ) & 0xff] ^ (v       ));

        v = rdk[k + 1];
        pt[ 4] = (byte)(Sd[(t1 >>> 24)       ] ^ (v >>> 24));
        pt[ 5] = (byte)(Sd[(t0 >>> 16) & 0xff] ^ (v >>> 16));
        pt[ 6] = (byte)(Sd[(t3 >>>  8) & 0xff] ^ (v >>>  8));
        pt[ 7] = (byte)(Sd[(t2       ) & 0xff] ^ (v       ));

        v = rdk[k + 2];
        pt[ 8] = (byte)(Sd[(t2 >>> 24)       ] ^ (v >>> 24));
        pt[ 9] = (byte)(Sd[(t1 >>> 16) & 0xff] ^ (v >>> 16));
        pt[10] = (byte)(Sd[(t0 >>>  8) & 0xff] ^ (v >>>  8));
        pt[11] = (byte)(Sd[(t3       ) & 0xff] ^ (v       ));

        v = rdk[k + 3];
        pt[12] = (byte)(Sd[(t3 >>> 24)       ] ^ (v >>> 24));
        pt[13] = (byte)(Sd[(t2 >>> 16) & 0xff] ^ (v >>> 16));
        pt[14] = (byte)(Sd[(t1 >>>  8) & 0xff] ^ (v >>>  8));
        pt[15] = (byte)(Sd[(t0       ) & 0xff] ^ (v       ));
    }

    /**
     * Destroy all sensitive information in this object.
     */
    public final void finalize() {
        if (rek != null) {
            for (int i = 0; i < rek.length; i++) {
                rek[i] = 0;
            }
            rek = null;
        }
        if (rdk != null) {
            for (int i = 0; i < rdk.length; i++) {
                rdk[i] = 0;
            }
            rdk = null;
        }
    }
}



/*
@GROUP
Crypto
@SYNTAX
answer = AES ("encrypt", plain, key) 
answer = AES ("e",       plain, key) 
answer = AES ("decrypt", cipher, key) 
answer = AES ("d",       cipher, key) 
@DOC
does encryption and descrption using the AES (advanced encryption standard) algorithm
@EXAMPLES
<programlisting>
> k=str2num("0987098709870987")  
k=[48,57,56,55,48,57,56,55,48,57,56,55,48,57,56,55] 

> a=str2num("asdfasdfasdfasdf") 
a=[97,115,100,102,97,115,100,102,97,115,100,102,97,115,100,102] 

> b=aes("e",a,k) 
b=[-103,34,84,18,-46,-58,35,89,80,17,81,118,-4,-15,-93,-31] 

> c=aes("d",b,k) 
c=[97,115,100,102,97,115,100,102,97,115,100,102,97,115,100,102] 

> num2str(c) 
 ans = asdfasdfasdfasdf 
</programlisting>
@NOTES
@SEE
*/

⌨️ 快捷键说明

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