/** Compute the next round key from the previous round key. */ private static void advanceRoundKey(RoundKey prevprev, RoundKey prev, RoundKey next) { // Column 0. next.key00 = prevprev.key00 ^ byteSub[prev.key03]; next.key10 = prevprev.key10 ^ byteSub[prev.key13]; next.key20 = prevprev.key20 ^ byteSub[prev.key23]; next.key30 = prevprev.key30 ^ byteSub[prev.key33]; // Column 1. next.key01 = prevprev.key01 ^ next.key00; next.key11 = prevprev.key11 ^ next.key10; next.key21 = prevprev.key21 ^ next.key20; next.key31 = prevprev.key31 ^ next.key30; // Column 2. next.key02 = prevprev.key02 ^ next.key01; next.key12 = prevprev.key12 ^ next.key11; next.key22 = prevprev.key22 ^ next.key21; next.key32 = prevprev.key32 ^ next.key31; // Column 3. next.key03 = prevprev.key03 ^ next.key02; next.key13 = prevprev.key13 ^ next.key12; next.key23 = prevprev.key23 ^ next.key22; next.key33 = prevprev.key33 ^ next.key32; }
/** * Set the key to be used for all subsequent encryptions and decryptions. After this method * returns, <TT>theKey</TT> is no longer needed and may be erased (set to all 0s). The length of * <TT>theKey</TT> must be at least 32. Only the first 32 bytes are used. * * @param theKey Key (byte array). * @exception NullPointerException (unchecked exception) Thrown if <TT>theKey</TT> is null. * @exception IllegalArgumentException (unchecked exception) Thrown if <TT>theKey.length</TT> < * 32. */ public void setKey(byte[] theKey) { // Verify arguments. if (theKey.length < 32) { throw new IllegalArgumentException("Key is not 32 bytes"); } // Allocate storage for round keys if necessary. if (expandedKey == null) { expandedKey = new RoundKey[ROUND_KEY_COUNT]; for (int i = 0; i < ROUND_KEY_COUNT; ++i) { expandedKey[i] = new RoundKey(); } } // Fill in first two round keys from theKey. RoundKey roundKey; roundKey = expandedKey[0]; roundKey.key00 = theKey[0] & 0xFF; roundKey.key10 = theKey[1] & 0xFF; roundKey.key20 = theKey[2] & 0xFF; roundKey.key30 = theKey[3] & 0xFF; roundKey.key01 = theKey[4] & 0xFF; roundKey.key11 = theKey[5] & 0xFF; roundKey.key21 = theKey[6] & 0xFF; roundKey.key31 = theKey[7] & 0xFF; roundKey.key02 = theKey[8] & 0xFF; roundKey.key12 = theKey[9] & 0xFF; roundKey.key22 = theKey[10] & 0xFF; roundKey.key32 = theKey[11] & 0xFF; roundKey.key03 = theKey[12] & 0xFF; roundKey.key13 = theKey[13] & 0xFF; roundKey.key23 = theKey[14] & 0xFF; roundKey.key33 = theKey[15] & 0xFF; roundKey = expandedKey[1]; roundKey.key00 = theKey[16] & 0xFF; roundKey.key10 = theKey[17] & 0xFF; roundKey.key20 = theKey[18] & 0xFF; roundKey.key30 = theKey[19] & 0xFF; roundKey.key01 = theKey[20] & 0xFF; roundKey.key11 = theKey[21] & 0xFF; roundKey.key21 = theKey[22] & 0xFF; roundKey.key31 = theKey[23] & 0xFF; roundKey.key02 = theKey[24] & 0xFF; roundKey.key12 = theKey[25] & 0xFF; roundKey.key22 = theKey[26] & 0xFF; roundKey.key32 = theKey[27] & 0xFF; roundKey.key03 = theKey[28] & 0xFF; roundKey.key13 = theKey[29] & 0xFF; roundKey.key23 = theKey[30] & 0xFF; roundKey.key33 = theKey[31] & 0xFF; // Fill in remaining round keys. int rcon = 1; for (int i = 2; i < 14; i += 2) { advanceRoundKey(expandedKey[i - 2], expandedKey[i - 1], expandedKey[i], rcon); rcon = xtime[rcon]; advanceRoundKey(expandedKey[i - 1], expandedKey[i], expandedKey[i + 1]); } advanceRoundKey(expandedKey[12], expandedKey[13], expandedKey[14], rcon); }