?? rijndaelengine.java
字號:
private long[][] generateWorkingKey( byte[] key) { int KC; int t, rconpointer = 0; int keyBits = key.length * 8; byte[][] tk = new byte[4][MAXKC]; long[][] W = new long[MAXROUNDS+1][4]; switch (keyBits) { case 128: KC = 4; break; case 160: KC = 5; break; case 192: KC = 6; break; case 224: KC = 7; break; case 256: KC = 8; break; default : throw new IllegalArgumentException("Key length not 128/160/192/224/256 bits."); } if (keyBits >= blockBits) { ROUNDS = KC + 6; } else { ROUNDS = (BC / 8) + 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)*(BC / 8)); j++, t++) { for (int i = 0; i < 4; i++) { W[t / (BC / 8)][i] |= (long)(tk[i][j] & 0xff) << ((t * 8) % BC); } } // // while not enough round key material calculated // calculate new values // while (t < (ROUNDS+1)*(BC/8)) { 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)*(BC/8)); j++, t++) { for (int i = 0; i < 4; i++) { W[t / (BC/8)][i] |= (long)(tk[i][j] & 0xff) << ((t * 8) % (BC)); } } } return W; } private int BC; private long BC_MASK; private int ROUNDS; private int blockBits; private long[][] workingKey; private long A0, A1, A2, A3; private boolean forEncryption; private byte[] shifts0SC; private byte[] shifts1SC; /** * default constructor - 128 bit block size. */ public RijndaelEngine() { this(128); } /** * basic constructor - set the cipher up for a given blocksize * * @param blockBits the blocksize in bits, must be 128, 192, or 256. */ public RijndaelEngine( int blockBits) { switch (blockBits) { case 128: BC = 32; BC_MASK = 0xffffffffL; shifts0SC = shifts0[0]; shifts1SC = shifts1[0]; break; case 160: BC = 40; BC_MASK = 0xffffffffffL; shifts0SC = shifts0[1]; shifts1SC = shifts1[1]; break; case 192: BC = 48; BC_MASK = 0xffffffffffffL; shifts0SC = shifts0[2]; shifts1SC = shifts1[2]; break; case 224: BC = 56; BC_MASK = 0xffffffffffffffL; shifts0SC = shifts0[3]; shifts1SC = shifts1[3]; break; case 256: BC = 64; BC_MASK = 0xffffffffffffffffL; shifts0SC = shifts0[4]; shifts1SC = shifts1[4]; break; default: throw new IllegalArgumentException("unknown blocksize to Rijndael"); } this.blockBits = blockBits; } /** * initialise a Rijndael 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 Rijndael init - " + params.getClass().getName()); } public String getAlgorithmName() { return "Rijndael"; } public int getBlockSize() { return BC / 2; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey == null) { throw new IllegalStateException("Rijndael engine not initialised"); } if ((inOff + (BC / 2)) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + (BC / 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 BC / 2; } 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 != BC; j += 8) { A0 |= (long)(bytes[index++] & 0xff) << j; A1 |= (long)(bytes[index++] & 0xff) << j; A2 |= (long)(bytes[index++] & 0xff) << j; A3 |= (long)(bytes[index++] & 0xff) << j; } } private final void packBlock( byte[] bytes, int off) { int index = off; for (int j = 0; j != BC; 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( long[][] rk) { int r; // // begin with a key addition // KeyAddition(rk[0]); // // ROUNDS-1 ordinary rounds // for (r = 1; r < ROUNDS; r++) { Substitution(S); ShiftRow(shifts0SC); MixColumn(); KeyAddition(rk[r]); } // // Last round is special: there is no MixColumn // Substitution(S); ShiftRow(shifts0SC); KeyAddition(rk[ROUNDS]); } private final void decryptBlock( long[][] 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); ShiftRow(shifts1SC); // // ROUNDS-1 ordinary rounds // for (r = ROUNDS-1; r > 0; r--) { KeyAddition(rk[r]); InvMixColumn(); Substitution(Si); ShiftRow(shifts1SC); } // // End with the extra key addition // KeyAddition(rk[0]); }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -