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

📄 aes.java

📁 JAVA 数学程序库 提供常规的数值计算程序包
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package jmathlib.toolbox.crypto;

/* This file is part or JMathLib 
 * */

import jmathlib.core.tokens.*;
import jmathlib.core.tokens.numbertokens.DoubleNumberToken;
import jmathlib.core.functions.ExternalFunction;


/**An external function for computing a mesh of a matrix  */
public class aes extends ExternalFunction
{
    /**returns two  matrices 
    * @param operands[0] = x values (e.g. [-2:0.2:2]) 
    * @param operands[1] = y values (e.g. [-2:0.2:2])
    * @param operands[2] = y values (e.g. [-2:0.2:2])
    * @return [X,Y] as matrices                                 */
    public OperandToken evaluate(Token[] operands)
    {

        // one operand 
        if (getNArgIn(operands)!=3)
            throwMathLibException("AES: number of input arguments != 3");

        if (!(operands[0] instanceof CharToken))
            throwMathLibException("AES: first argument: encrypt or decrypt");
        
        if ( !(operands[1] instanceof DoubleNumberToken) || 
             !(operands[2] instanceof DoubleNumberToken)    )
            throwMathLibException("AES: works only on numbers");

        // get data from arguments
        String     type = ((CharToken)operands[0]).getValue();
        double[][] x    = ((DoubleNumberToken)operands[1]).getReValues();
        double[][] y    = ((DoubleNumberToken)operands[2]).getReValues();

        // AES works only on blocks of 16 bytes = 128bits
        if ((x.length    !=  1) ||
            (x[0].length != 16) ||
            (y.length    !=  1) ||
            (y[0].length != 16)    )
            throwMathLibException("AES: works only on row vectors with 16 bytes");

       
        // convert key from double to byte array
        byte[] cipherKey = new byte[16];
        for (int i=0; i<16; i++)
        {
            // check if key numbers are positiv and only 8 bits max
            if ((y[0][i]<0) || (y[0][i]>255))
                throwMathLibException("AES expects input between 0 (0x0) and 255 (0xff)");     

            cipherKey[i] = new Double(y[0][i]).byteValue();
        }

        // prepare key
        makeKey(cipherKey, 128 );

        // allocate memory of plain text and cipher text
        byte[] plainText  = { 0, 0, 0, 0,  0, 0, 0, 0,
                              0, 0, 0, 0,  0, 0, 0, 0 };
        byte[] cipherText = { 0, 0, 0, 0,  0, 0, 0, 0,
                              0, 0, 0, 0,  0, 0, 0, 0 };
       
        // allocate memry for return numbers
        double[][] ret = new double[1][16];
       

        // encryption or decryption
        if (type.toLowerCase().substring(0,1).equals("e"))
        {
            // encrypt
 
            // convert plain text to byte array
            for (int i=0; i<16; i++)
            {
                // check if  numbers are positiv and only 8 bits max
                if ((x[0][i]<0) || (x[0][i]>255))
                    throwMathLibException("AES expects plain text between 0 (0x0) and 255 (0xff)");     
                
                plainText[i] = new Double(x[0][i]).byteValue();
            }
            
            // compute encryption
            encrypt(plainText, cipherText);

            // convert byte to double
            for (int i=0; i<16; i++)
            {
                ret[0][i] = (double)(cipherText[i]);

                // move range -128 to 127  into the range 0 to 255
                if (ret[0][i]<0)
                    ret[0][i] = 256 + ret[0][i];
            }

        }
        else
        {
            // decrypt
            
            // convert cipher text to byte array
            for (int i=0; i<16; i++)
            {
                // check if  numbers are positiv and only 8 bits max
                if ((x[0][i]<0) || (x[0][i]>255))
                    throwMathLibException("AES expects cypher text between 0 (0x0) and 255 (0xff)");     

                cipherText[i] = new Double(x[0][i]).byteValue();
            }

            // compute decryption
            decrypt(cipherText, plainText);

            // convert byte to double
            for (int i=0; i<16; i++)
            {
                ret[0][i] = (double)(plainText[i]);

                // move range -128 to 127  into the range 0 to 255
                if (ret[0][i]<0)
                    ret[0][i] = 256 + ret[0][i];
            }


        } // end encrypt/decrypt
        
        //try {
        //    System.out.println("cipher Key "      + new String(cipherKey,  "UTF8") );
        //    System.out.println("plaintext block  "+ new String(plainText,  "UTF8") );
        //    System.out.println("ciphertext block "+ new String(cipherText, "UTF8") );
        //}
        //catch (Exception e){;}
        
        
        return new DoubleNumberToken(ret);

    } // end eval



/**
 * AES.java
 *
 * The Advanced Encryption Standard (Rijndael, aka AES) block cipher,
 * designed by J. Daemen and V. Rijmen.
 *
 * @author Paulo S. L. M. Barreto
 *
 * This software is hereby placed in the public domain.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
//public final class AES { //extends BlockCipher {

//    public AES() {
//    }

    /**
     * AES block size in bits
     * (N.B. the Rijndael algorithm itself allows for other sizes).
     */
    public static final int BLOCK_BITS  = 128;

    /**
     * AES block size in bytes
     * (N.B. the Rijndael algorithm itself allows for other sizes).
     */
    public static final int BLOCK_SIZE  = (BLOCK_BITS >>> 3);

    
    public static final int DIR_DECRYPT = 1;
    public static final int DIR_ENCRYPT = 2;
    public static final int DIR_BOTH    = 3;
    
    
    /**
     * Block size in bytes
     */
    public final int blockSize() {
        return BLOCK_SIZE;
    }

    /**
     * Block size in bytes
     */
    public final int keySize() {
        return Nk << 5;
    }

    /**
     * Substitution table (S-box).
     */
    private static final String SS =
        "\u637C\u777B\uF26B\u6FC5\u3001\u672B\uFED7\uAB76" +
        "\uCA82\uC97D\uFA59\u47F0\uADD4\uA2AF\u9CA4\u72C0" +
        "\uB7FD\u9326\u363F\uF7CC\u34A5\uE5F1\u71D8\u3115" +
        "\u04C7\u23C3\u1896\u059A\u0712\u80E2\uEB27\uB275" +
        "\u0983\u2C1A\u1B6E\u5AA0\u523B\uD6B3\u29E3\u2F84" +
        "\u53D1\u00ED\u20FC\uB15B\u6ACB\uBE39\u4A4C\u58CF" +
        "\uD0EF\uAAFB\u434D\u3385\u45F9\u027F\u503C\u9FA8" +
        "\u51A3\u408F\u929D\u38F5\uBCB6\uDA21\u10FF\uF3D2" +
        "\uCD0C\u13EC\u5F97\u4417\uC4A7\u7E3D\u645D\u1973" +
        "\u6081\u4FDC\u222A\u9088\u46EE\uB814\uDE5E\u0BDB" +
        "\uE032\u3A0A\u4906\u245C\uC2D3\uAC62\u9195\uE479" +
        "\uE7C8\u376D\u8DD5\u4EA9\u6C56\uF4EA\u657A\uAE08" +
        "\uBA78\u252E\u1CA6\uB4C6\uE8DD\u741F\u4BBD\u8B8A" +
        "\u703E\uB566\u4803\uF60E\u6135\u57B9\u86C1\u1D9E" +
        "\uE1F8\u9811\u69D9\u8E94\u9B1E\u87E9\uCE55\u28DF" +
        "\u8CA1\u890D\uBFE6\u4268\u4199\u2D0F\uB054\uBB16";

    private static final byte[]
        Se = new byte[256];

    private static final int[]
        Te0 = new int[256],
        Te1 = new int[256],
        Te2 = new int[256],
        Te3 = new int[256];

    private static final byte[]
        Sd = new byte[256];

    private static final int[]
        Td0 = new int[256],
        Td1 = new int[256],
        Td2 = new int[256],
        Td3 = new int[256];

    /**
     * Round constants
     */
    private static final int[]
        rcon = new int[10]; /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */

    /**
     * Number of rounds (depends on key size).
     */
    private int Nr = 0;

    private int Nk = 0;

    private int Nw = 0;

    /**
     * Encryption key schedule
     */
    private int rek[] = null;

    /**
     * Decryption key schedule
     */
    private int rdk[] = null;

    static {
        /*
            Te0[x] = Se[x].[02, 01, 01, 03];
            Te1[x] = Se[x].[03, 02, 01, 01];
            Te2[x] = Se[x].[01, 03, 02, 01];
            Te3[x] = Se[x].[01, 01, 03, 02];

            Td0[x] = Sd[x].[0e, 09, 0d, 0b];
            Td1[x] = Sd[x].[0b, 0e, 09, 0d];
            Td2[x] = Sd[x].[0d, 0b, 0e, 09];
            Td3[x] = Sd[x].[09, 0d, 0b, 0e];
        */
        int ROOT = 0x11B;
        int s1, s2, s3, i1, i2, i4, i8, i9, ib, id, ie, t;
        for (i1 = 0; i1 < 256; i1++) {
            char c = SS.charAt(i1 >>> 1);
            s1 = (byte)((i1 & 1) == 0 ? c >>> 8 : c) & 0xff;
            s2 = s1 << 1;
            if (s2 >= 0x100) {
                s2 ^= ROOT;
            }
            s3 = s2 ^ s1;
            i2 = i1 << 1;
            if (i2 >= 0x100) {
                i2 ^= ROOT;
            }
            i4 = i2 << 1;
            if (i4 >= 0x100) {
                i4 ^= ROOT;
            }
            i8 = i4 << 1;
            if (i8 >= 0x100) {
                i8 ^= ROOT;
            }
            i9 = i8 ^ i1;
            ib = i9 ^ i2;
            id = i9 ^ i4;
            ie = i8 ^ i4 ^ i2;

            Se[i1] = (byte)s1;
            Te0[i1] = t = (s2 << 24) | (s1 << 16) | (s1 << 8) | s3;
            Te1[i1] = (t >>>  8) | (t  << 24);
            Te2[i1] = (t >>> 16) | (t  << 16);
            Te3[i1] = (t >>> 24) | (t  <<  8);

            Sd[s1] = (byte)i1;
            Td0[s1] = t = (ie << 24) | (i9 << 16) | (id << 8) | ib;
            Td1[s1] = (t >>>  8) | (t  << 24);
            Td2[s1] = (t >>> 16) | (t  << 16);
            Td3[s1] = (t >>> 24) | (t  <<  8);
		}
        /*
         * round constants
         */
        int r = 1;
        rcon[0] = r << 24;
        for (int i = 1; i < 10; i++) {
            r <<= 1;
            if (r >= 0x100) {
                r ^= ROOT;
            }
            rcon[i] = r << 24;
        }
    }

    /**
     * Expand a cipher key into a full encryption key schedule.
     *
     * @param   cipherKey   the cipher key (128, 192, or 256 bits).
     */
    private final void expandKey(byte[] cipherKey) {
        int temp, r = 0;
        for (int i = 0, k = 0; i < Nk; i++, k += 4) {
            rek[i] =
                ((cipherKey[k    ]       ) << 24) |
                ((cipherKey[k + 1] & 0xff) << 16) |
                ((cipherKey[k + 2] & 0xff) <<  8) |
                ((cipherKey[k + 3] & 0xff));
        }
        for (int i = Nk, n = 0; i < Nw; i++, n--) {
            temp = rek[i - 1];
            if (n == 0) {
            	n = Nk;
                temp =
                    ((Se[(temp >>> 16) & 0xff]       ) << 24) |
                    ((Se[(temp >>>  8) & 0xff] & 0xff) << 16) |

⌨️ 快捷键说明

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