📄 aesengine.java
字号:
a2 = (a2 != 0) ? (Logtable[a2 & 0xff] & 0xff) : -1; a3 = (a3 != 0) ? (Logtable[a3 & 0xff] & 0xff) : -1; r0 |= ((mul0xe(a0) ^ mul0xb(a1) ^ mul0xd(a2) ^ mul0x9(a3)) & 0xff) << j; r1 |= ((mul0xe(a1) ^ mul0xb(a2) ^ mul0xd(a3) ^ mul0x9(a0)) & 0xff) << j; r2 |= ((mul0xe(a2) ^ mul0xb(a3) ^ mul0xd(a0) ^ mul0x9(a1)) & 0xff) << j; r3 |= ((mul0xe(a3) ^ mul0xb(a0) ^ mul0xd(a1) ^ mul0x9(a2)) & 0xff) << j; } A0 = r0; A1 = r1; A2 = r2; A3 = r3; } /** * Calculate the necessary round keys * The number of calculations depends on keyBits and BLOCK_BITS */ private int[][] generateWorkingKey( byte[] key) { int KC; int t, rconpointer = 0; int keyBits = key.length * 8; byte[][] tk = new byte[4][MAXKC]; int[][] W = new int[MAXROUNDS+1][4]; switch (keyBits) { case 128: KC = 4; break; case 192: KC = 6; break; case 256: KC = 8; break; default: throw new IllegalArgumentException("Key length not 128/192/256 bits."); } if (keyBits >= BLOCK_BITS) { ROUNDS = KC + 6; } else { ROUNDS = 4 + 6; } // // copy the key into the processing area // int index = 0; for (int i = 0; i < key.length; i++) { tk[i % 4][i / 4] = key[index++]; } t = 0; // // copy values into round key array // for (int j = 0; (j < KC) && (t < (ROUNDS+1) * 4); j++, t++) { for (int i = 0; i < 4; i++) { W[t / 4][i] |= (int)(tk[i][j] & 0xff) << ((t * 8) % 32); } } // // while not enough round key material calculated // calculate new values // while (t < (ROUNDS+1) * 4) { for (int i = 0; i < 4; i++) { tk[i][0] ^= S[tk[(i+1)%4][KC-1] & 0xff]; } tk[0][0] ^= rcon[rconpointer++]; if (KC <= 6) { for (int j = 1; j < KC; j++) { for (int i = 0; i < 4; i++) { tk[i][j] ^= tk[i][j-1]; } } } else { for (int j = 1; j < 4; j++) { for (int i = 0; i < 4; i++) { tk[i][j] ^= tk[i][j-1]; } } for (int i = 0; i < 4; i++) { tk[i][4] ^= S[tk[i][3] & 0xff]; } for (int j = 5; j < KC; j++) { for (int i = 0; i < 4; i++) { tk[i][j] ^= tk[i][j-1]; } } } // // copy values into round key array // for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(32/8)); j++, t++) { for (int i = 0; i < 4; i++) { W[t / (32/8)][i] |= (int)(tk[i][j] & 0xff) << ((t * 8) % (32)); } } } return W; } private int ROUNDS; private int[][] workingKey; private int A0, A1, A2, A3; private boolean forEncryption; private static final int BLOCK_SIZE = 16; private static final int BLOCK_BITS = 128; /** * default constructor - 128 bit block size. */ public AESEngine() { } /** * initialise an AES 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(((KeyParameter)params).getKey()); this.forEncryption = forEncryption; return; } throw new IllegalArgumentException("invalid parameter passed to AES init - " + params.getClass().getName()); } public String getAlgorithmName() { return "AES"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey == null) { throw new IllegalStateException("AES engine not initialised"); } if ((inOff + (32 / 2)) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + (32 / 2)) > out.length) { throw new DataLengthException("output buffer too short"); } if (forEncryption) { unpackBlock(in, inOff); encryptBlock(workingKey); packBlock(out, outOff); } else { unpackBlock(in, inOff); decryptBlock(workingKey); packBlock(out, outOff); } return BLOCK_SIZE; } public void reset() { } private final void unpackBlock( byte[] bytes, int off) { int index = off; A0 = (bytes[index++] & 0xff); A1 = (bytes[index++] & 0xff); A2 = (bytes[index++] & 0xff); A3 = (bytes[index++] & 0xff); for (int j = 8; j != 32; j += 8) { A0 |= (bytes[index++] & 0xff) << j; A1 |= (bytes[index++] & 0xff) << j; A2 |= (bytes[index++] & 0xff) << j; A3 |= (bytes[index++] & 0xff) << j; } } private final void packBlock( byte[] bytes, int off) { int index = off; for (int j = 0; j != 32; j += 8) { bytes[index++] = (byte)(A0 >> j); bytes[index++] = (byte)(A1 >> j); bytes[index++] = (byte)(A2 >> j); bytes[index++] = (byte)(A3 >> j); } } private final void encryptBlock( int[][] rk) { int r; // // begin with a key addition // KeyAddition(rk[0]); // // ROUNDS-1 ordinary rounds // for (r = 1; r < ROUNDS; r++) { Substitution(S); ShiftRow(); MixColumn(); KeyAddition(rk[r]); } // // Last round is special: there is no MixColumn // Substitution(S); ShiftRow(); KeyAddition(rk[ROUNDS]); } private final void decryptBlock( int[][] rk) { int r; // To decrypt: apply the inverse operations of the encrypt routine, // in opposite order // // (KeyAddition is an involution: it 's equal to its inverse) // (the inverse of Substitution with table S is Substitution with the inverse table of S) // (the inverse of Shiftrow is Shiftrow over a suitable distance) // // First the special round: // without InvMixColumn // with extra KeyAddition // KeyAddition(rk[ROUNDS]); Substitution(Si); InvShiftRow(); // // ROUNDS-1 ordinary rounds // for (r = ROUNDS-1; r > 0; r--) { KeyAddition(rk[r]); InvMixColumn(); Substitution(Si); InvShiftRow(); } // // End with the extra key addition // KeyAddition(rk[0]); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -