📄 aesjcop.java
字号:
// T-boxes. // 4x4 byte[] G, iG; G = new byte[] { 2,1, 1, 3, 3, 2,1, 1, 1, 3, 2,1,1, 1, 3, 2}; iG = new byte[] {14,9,13,11,11,14,9,13,13,11,14,9,9,13,11,14}; short q; for ( t = 0; t < 256; ++t ) { // cannot use variables i and j here because of mul4 k=(short)(t<<1); if (mode==0x01) { q = S[t]; box[k] = mul4( q, G[0], G[1] ) ; box[k+1] = mul4( q, G[2], G[3] ) ; box[512+k] = mul4( q, G[4], G[5] ) ; box[512+k+1] = mul4( q, G[6], G[7] ) ; cox[k] = mul4( q, G[8], G[9] ) ; cox[k+1] = mul4( q, G[10], G[11] ) ; cox[512+k] = mul4( q, G[12], G[13] ) ; cox[512+k+1] = mul4( q, G[14], G[15] ) ; } else if (mode==0x03) { q = Si[t]; box[k] = mul4( q, iG[0], iG[1] ); box[k+1] = mul4( q, iG[2], iG[3] ); box[512+k] = mul4( q, iG[4], iG[5] ); box[512+k+1] = mul4( q, iG[6], iG[7] ); cox[k] = mul4( q, iG[8], iG[9] ); cox[k+1] = mul4( q, iG[10], iG[11] ); cox[512+k] = mul4( q, iG[12], iG[13] ); cox[512+k+1] = mul4( q, iG[14], iG[15] ); } else if (mode==0x02) { q = t; box[k] = mul4( q, iG[0], iG[1] ); box[k+1] = mul4( q, iG[2], iG[3] ); box[512+k] = mul4( q, iG[4], iG[5] ); box[512+k+1] = mul4( q, iG[6], iG[7] ); cox[k] = mul4( q, iG[8], iG[9] ); cox[k+1] = mul4( q, iG[10], iG[11] ); cox[512+k] = mul4( q, iG[12], iG[13] ); cox[512+k+1] = mul4( q, iG[14], iG[15] ); } } // for } /// Return the number of rounds for a given Rijndael's key and block sizes. // @param keySize The size of the user key material in bytes. // @param blockSize The desired block size in bytes. // @return The number of rounds for a given Rijndael's key and block sizes. private short getRounds( short keySize, short blockSize ) { switch ( keySize ) { case 16: return blockSize == 16 ? (short)10 : ( blockSize == 24 ? (short)12 : (short)14 ); case 24: return blockSize != 32 ? (short)12 : (short)14; default: // 32 bytes = 256 bits return (short)14; } } /// Set the key. private void setKey( byte[] key, byte mode ) { ROUNDS = getRounds( KEY_SIZE, BLOCK_SIZE ); K = new short[(ROUNDS + 1)*BC*2]; if ( key.length != KEY_SIZE ) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); short ROUND_KEY_COUNT = (short)(( ROUNDS + 1 ) * BC); short KC = (short)(KEY_SIZE >> 2); short KC2 = (short)(KEY_SIZE >> 1); short[] tk = new short[KC2]; // Copy user material bytes into temporary ints. for ( i = 0, j = 0; i < KC2; ) { tk[i++] = (short)( ( key[j++] & 0xFF ) << 8 | ( key[j++] & 0xFF ) ); } // Copy values into round key arrays. t = 0; for ( j = 0; ( j < KC ) && ( t < ROUND_KEY_COUNT ); ++j, ++t ) { if (mode==0x01) k = (short)(2*(t / BC*BC+t % BC)); else k = (short)(2*((ROUNDS - ( t / BC ))*BC+t % BC)); K[k] = tk[j*2]; K[k+1] = tk[j*2+1]; } short tth, ttl; r = 0; while ( t < ROUND_KEY_COUNT ) { // Extrapolate using phi (the round key evolution function). tth = tk[(KC - 1)*2]; ttl = tk[(KC-1)*2+1]; tk[0] ^= ( S[( tth ) & 0xFF] & 0xFF ) << 8 ^ ( S[( ttl >>> 8 ) & 0xFF] & 0xFF ) ^ ( rcon[r++] & 0xFF ) << 8; tk[1] ^= ( S[ ttl & 0xFF] & 0xFF ) << 8 ^ ( S[( tth >>> 8 ) & 0xFF] & 0xFF ); if ( KC != 8 ) for ( i = 2, j = 0; i < KC2; ) { tk[i++] ^= tk[j++]; } else { for ( i = 1, j = 0; i < KC / 2; ) { tk[i*2] ^= tk[j*2]; tk[i*2+1] ^= tk[j*2+1]; i++; j++; } tth = tk[(KC / 2 - 1)*2]; ttl = tk[(KC / 2 - 1)*2+1]; tk[(KC / 2)*2] ^= ( S[( tth ) & 0xFF] & 0xFF ) ^ ( S[( tth >>> 8 ) & 0xFF] & 0xFF ) << 8; tk[(KC/2)*2+1] ^= ( S[ ttl & 0xFF] & 0xFF ) ^ ( S[( ttl >>> 8 ) & 0xFF] & 0xFF ) << 8; for ( j = (short)(KC / 2), i = (short)(j + 1); i < KC; ) { tk[i*2] ^= tk[j*2]; tk[i*2+1] ^= tk[j*2+1]; i++; j++; } } // Copy values into round key arrays. for ( j = 0; ( j < KC ) && ( t < ROUND_KEY_COUNT ); ++j, ++t ) { if (mode==0x01) k = (short)(2*(t / BC*BC+t % BC)); else k = (short)( 2*((ROUNDS - ( t / BC ))*BC+t % BC) ); K[k] = tk[j*2]; K[k+1] = tk[j*2+1]; } } // Only for Decryption if (mode==0x02) for ( r = 1; r < ROUNDS; ++r ) // inverse MixColumn where needed for ( j = 0; j < BC; ++j ) { tth = K[(r*BC+j)*2]; ttl = K[(r*BC+j)*2+1]; i = (short)(( tth >>> 8 ) & 0xFF); k = (short)(( tth ) & 0xFF); s = (short)(( ttl >>> 8 ) & 0xFF); t = (short)( ttl & 0xFF); K[(r*BC+j)*2] = (short)( box[i*2] ^ box[512+k*2] ^ cox[s*2] ^ cox[512+t*2] ); K[(r*BC+j)*2+1] = (short)( box[i*2+1] ^ box[512+k*2+1] ^ cox[s*2+1] ^ cox[512+t*2+1] ); } } private void copyShortArray(short[] a, short[] b) { if (a.length!=b.length) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); for(short i=0;i<a.length;i++) b[i] = a[i]; } // Block encryption routines. /// Encrypt a block. public void encrypt( byte[] clearText, short clearOff, byte[] cipherText, short cipherOff ) { short SC = ( BC == 4 ? (short)0 : ( BC == 6 ? (short)1 : (short)2 ) ); short s1 = shifts[SC*4+1*2+0]; short s2 = shifts[SC*4+2*2+0]; short s3 = shifts[SC*4+3*2+0]; short[] a = new short[BC*2]; short[] tmp = new short[BC*2]; // temporary work array short tth, ttl; for ( i = 0; i < BC; ++i ) // plaintext to ints + key { tmp[i*2] = (short)( ( ( clearText[clearOff++] & 0xFF ) << 8 | ( clearText[clearOff++] & 0xFF ) ) ^ K[(0*BC+i)*2] ); tmp[i*2+1] = (short)( ( ( clearText[clearOff++] & 0xFF ) << 8 | ( clearText[clearOff++] & 0xFF ) ) ^ K[(0*BC+i)*2+1] ); } // Apply round transforms. for ( r = 1; r < ROUNDS; ++r ) { for ( i = 0; i < BC; ++i ) { j = (short)(( tmp[ i*2 ] >> 8 ) & 0xFF); k = (short)(( tmp[(( i + s1 ) % BC)*2] ) & 0xFF); s = (short)(( tmp[(( i + s2 ) % BC)*2+1] >> 8 ) & 0xFF); t = (short)( tmp[(( i + s3 ) % BC)*2+1] & 0xFF); a[i*2] = (short)(box[j*2] ^ box[512+k*2] ^ cox[s*2] ^ cox[512+t*2] ^ K[(r*BC+i)*2]); a[i*2+1] = (short)(box[j*2+1] ^ box[512+k*2+1] ^ cox[s*2+1] ^ cox[512+t*2+1] ^ K[(r*BC+i)*2+1]); } copyShortArray( a, tmp); } // Last round is special. for ( i = 0; i < BC; ++i ) { tth = K[(ROUNDS*BC+i)*2]; ttl = K[(ROUNDS*BC+i)*2+1]; cipherText[cipherOff++] = (byte) ( S[( tmp[ i*2 ] >>> 8 ) & 0xFF] ^ ( tth >>> 8 ) ); cipherText[cipherOff++] = (byte) ( S[( tmp[(( i + s1 ) % BC)*2] ) & 0xFF] ^ ( tth & 0xff ) ); cipherText[cipherOff++] = (byte) ( S[( tmp[(( i + s2 ) % BC)*2+1] >>> 8 ) & 0xFF] ^ ( ttl >>> 8 ) ); cipherText[cipherOff++] = (byte) ( S[ tmp[(( i + s3 ) % BC)*2+1] & 0xFF] ^ ( ttl & 0xff ) ); } } /// Decrypt a block. public void decrypt( byte[] cipherText, short cipherOff, byte[] clearText, short clearOff ) { short SC = ( BC == 4 ? (short)0 : ( BC == 6 ? (short)1 : (short)2 ) ); short s1 = shifts[SC*4+1*2+1]; short s2 = shifts[SC*4+2*2+1]; short s3 = shifts[SC*4+3*2+1]; short[] a = new short[BC*2]; short[] tmp = new short[BC*2]; // temporary work array //short i; short tth, ttl; for ( i = 0; i < BC; ++i ) // ciphertext to ints + key { tmp[i*2] = (short)( ( ( cipherText[cipherOff++] & 0xFF ) << 8 | ( cipherText[cipherOff++] & 0xFF ) ) ^ K[(0*BC+i)*2] ); tmp[i*2+1] = (short)( ( ( cipherText[cipherOff++] & 0xFF ) << 8 | ( cipherText[cipherOff++] & 0xFF ) ) ^ K[(0*BC+i)*2+1] ); } // Apply round transforms. for ( r = 1; r < ROUNDS; ++r ) { for ( i = 0; i < BC; ++i ) { j = (short)(( tmp[ i*2 ] >>> 8 ) & 0xFF); k = (short)(( tmp[(( i + s1 ) % BC)*2] ) & 0xFF); s = (short)(( tmp[(( i + s2 ) % BC)*2+1] >>> 8 ) & 0xFF); t = (short)( tmp[(( i + s3 ) % BC)*2+1] & 0xFF); a[i*2] = (short)(box[j*2] ^ box[512+k*2] ^ cox[s*2] ^ cox[512+t*2] ^ K[(r*BC+i)*2]); a[i*2+1] = (short)(box[j*2+1] ^ box[512+k*2+1] ^ cox[s*2+1] ^ cox[512+t*2+1] ^ K[(r*BC+i)*2+1]); } copyShortArray( a, tmp); } // Last round is special. for ( i = 0; i < BC; ++i ) { tth = K[(ROUNDS*BC+i)*2]; ttl = K[(ROUNDS*BC+i)*2+1]; clearText[clearOff++] = (byte) ( Si[( tmp[ i*2 ] >>> 8 ) & 0xFF] ^ ( tth >>> 8 ) ); clearText[clearOff++] = (byte) ( Si[( tmp[(( i + s1 ) % BC)*2] ) & 0xFF] ^ ( tth ) ); clearText[clearOff++] = (byte) ( Si[( tmp[(( i + s2 ) % BC)*2+1] >>> 8 ) & 0xFF] ^ ( ttl >>> 8 ) ); clearText[clearOff++] = (byte) ( Si[ tmp[(( i + s3 ) % BC)*2+1] & 0xFF] ^ ttl ); } }} // AesJcop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -